Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
Go
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Martin Stiemerling
Go
Commits
afc49c67
Commit
afc49c67
authored
7 months ago
by
Martin Stiemerling
Browse files
Options
Downloads
Patches
Plain Diff
copied netlink_linux.go to netlink_freebsd.go without modifying it
parent
310b1ea4
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/syscall/netlink_freebsd.go
+188
-0
188 additions, 0 deletions
src/syscall/netlink_freebsd.go
with
188 additions
and
0 deletions
src/syscall/netlink_freebsd.go
0 → 100644
+
188
−
0
View file @
afc49c67
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Netlink sockets and messages
package
syscall
import
(
"sync"
"unsafe"
)
// Round the length of a netlink message up to align it properly.
func
nlmAlignOf
(
msglen
int
)
int
{
return
(
msglen
+
NLMSG_ALIGNTO
-
1
)
&
^
(
NLMSG_ALIGNTO
-
1
)
}
// Round the length of a netlink route attribute up to align it
// properly.
func
rtaAlignOf
(
attrlen
int
)
int
{
return
(
attrlen
+
RTA_ALIGNTO
-
1
)
&
^
(
RTA_ALIGNTO
-
1
)
}
// NetlinkRouteRequest represents a request message to receive routing
// and link states from the kernel.
type
NetlinkRouteRequest
struct
{
Header
NlMsghdr
Data
RtGenmsg
}
func
(
rr
*
NetlinkRouteRequest
)
toWireFormat
()
[]
byte
{
b
:=
make
([]
byte
,
rr
.
Header
.
Len
)
*
(
*
uint32
)(
unsafe
.
Pointer
(
&
b
[
0
:
4
][
0
]))
=
rr
.
Header
.
Len
*
(
*
uint16
)(
unsafe
.
Pointer
(
&
b
[
4
:
6
][
0
]))
=
rr
.
Header
.
Type
*
(
*
uint16
)(
unsafe
.
Pointer
(
&
b
[
6
:
8
][
0
]))
=
rr
.
Header
.
Flags
*
(
*
uint32
)(
unsafe
.
Pointer
(
&
b
[
8
:
12
][
0
]))
=
rr
.
Header
.
Seq
*
(
*
uint32
)(
unsafe
.
Pointer
(
&
b
[
12
:
16
][
0
]))
=
rr
.
Header
.
Pid
b
[
16
]
=
rr
.
Data
.
Family
return
b
}
func
newNetlinkRouteRequest
(
proto
,
seq
,
family
int
)
[]
byte
{
rr
:=
&
NetlinkRouteRequest
{}
rr
.
Header
.
Len
=
uint32
(
NLMSG_HDRLEN
+
SizeofRtGenmsg
)
rr
.
Header
.
Type
=
uint16
(
proto
)
rr
.
Header
.
Flags
=
NLM_F_DUMP
|
NLM_F_REQUEST
rr
.
Header
.
Seq
=
uint32
(
seq
)
rr
.
Data
.
Family
=
uint8
(
family
)
return
rr
.
toWireFormat
()
}
var
pageBufPool
=
&
sync
.
Pool
{
New
:
func
()
any
{
b
:=
make
([]
byte
,
Getpagesize
())
return
&
b
}}
// NetlinkRIB returns routing information base, as known as RIB, which
// consists of network facility information, states and parameters.
func
NetlinkRIB
(
proto
,
family
int
)
([]
byte
,
error
)
{
s
,
err
:=
Socket
(
AF_NETLINK
,
SOCK_RAW
|
SOCK_CLOEXEC
,
NETLINK_ROUTE
)
if
err
!=
nil
{
return
nil
,
err
}
defer
Close
(
s
)
sa
:=
&
SockaddrNetlink
{
Family
:
AF_NETLINK
}
if
err
:=
Bind
(
s
,
sa
);
err
!=
nil
{
return
nil
,
err
}
wb
:=
newNetlinkRouteRequest
(
proto
,
1
,
family
)
if
err
:=
Sendto
(
s
,
wb
,
0
,
sa
);
err
!=
nil
{
return
nil
,
err
}
lsa
,
err
:=
Getsockname
(
s
)
if
err
!=
nil
{
return
nil
,
err
}
lsanl
,
ok
:=
lsa
.
(
*
SockaddrNetlink
)
if
!
ok
{
return
nil
,
EINVAL
}
var
tab
[]
byte
rbNew
:=
pageBufPool
.
Get
()
.
(
*
[]
byte
)
defer
pageBufPool
.
Put
(
rbNew
)
done
:
for
{
rb
:=
*
rbNew
nr
,
_
,
err
:=
Recvfrom
(
s
,
rb
,
0
)
if
err
!=
nil
{
return
nil
,
err
}
if
nr
<
NLMSG_HDRLEN
{
return
nil
,
EINVAL
}
rb
=
rb
[
:
nr
]
tab
=
append
(
tab
,
rb
...
)
msgs
,
err
:=
ParseNetlinkMessage
(
rb
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
m
:=
range
msgs
{
if
m
.
Header
.
Seq
!=
1
||
m
.
Header
.
Pid
!=
lsanl
.
Pid
{
return
nil
,
EINVAL
}
if
m
.
Header
.
Type
==
NLMSG_DONE
{
break
done
}
if
m
.
Header
.
Type
==
NLMSG_ERROR
{
return
nil
,
EINVAL
}
}
}
return
tab
,
nil
}
// NetlinkMessage represents a netlink message.
type
NetlinkMessage
struct
{
Header
NlMsghdr
Data
[]
byte
}
// ParseNetlinkMessage parses b as an array of netlink messages and
// returns the slice containing the NetlinkMessage structures.
func
ParseNetlinkMessage
(
b
[]
byte
)
([]
NetlinkMessage
,
error
)
{
var
msgs
[]
NetlinkMessage
for
len
(
b
)
>=
NLMSG_HDRLEN
{
h
,
dbuf
,
dlen
,
err
:=
netlinkMessageHeaderAndData
(
b
)
if
err
!=
nil
{
return
nil
,
err
}
m
:=
NetlinkMessage
{
Header
:
*
h
,
Data
:
dbuf
[
:
int
(
h
.
Len
)
-
NLMSG_HDRLEN
]}
msgs
=
append
(
msgs
,
m
)
b
=
b
[
dlen
:
]
}
return
msgs
,
nil
}
func
netlinkMessageHeaderAndData
(
b
[]
byte
)
(
*
NlMsghdr
,
[]
byte
,
int
,
error
)
{
h
:=
(
*
NlMsghdr
)(
unsafe
.
Pointer
(
&
b
[
0
]))
l
:=
nlmAlignOf
(
int
(
h
.
Len
))
if
int
(
h
.
Len
)
<
NLMSG_HDRLEN
||
l
>
len
(
b
)
{
return
nil
,
nil
,
0
,
EINVAL
}
return
h
,
b
[
NLMSG_HDRLEN
:
],
l
,
nil
}
// NetlinkRouteAttr represents a netlink route attribute.
type
NetlinkRouteAttr
struct
{
Attr
RtAttr
Value
[]
byte
}
// ParseNetlinkRouteAttr parses m's payload as an array of netlink
// route attributes and returns the slice containing the
// NetlinkRouteAttr structures.
func
ParseNetlinkRouteAttr
(
m
*
NetlinkMessage
)
([]
NetlinkRouteAttr
,
error
)
{
var
b
[]
byte
switch
m
.
Header
.
Type
{
case
RTM_NEWLINK
,
RTM_DELLINK
:
b
=
m
.
Data
[
SizeofIfInfomsg
:
]
case
RTM_NEWADDR
,
RTM_DELADDR
:
b
=
m
.
Data
[
SizeofIfAddrmsg
:
]
case
RTM_NEWROUTE
,
RTM_DELROUTE
:
b
=
m
.
Data
[
SizeofRtMsg
:
]
default
:
return
nil
,
EINVAL
}
var
attrs
[]
NetlinkRouteAttr
for
len
(
b
)
>=
SizeofRtAttr
{
a
,
vbuf
,
alen
,
err
:=
netlinkRouteAttrAndValue
(
b
)
if
err
!=
nil
{
return
nil
,
err
}
ra
:=
NetlinkRouteAttr
{
Attr
:
*
a
,
Value
:
vbuf
[
:
int
(
a
.
Len
)
-
SizeofRtAttr
]}
attrs
=
append
(
attrs
,
ra
)
b
=
b
[
alen
:
]
}
return
attrs
,
nil
}
func
netlinkRouteAttrAndValue
(
b
[]
byte
)
(
*
RtAttr
,
[]
byte
,
int
,
error
)
{
a
:=
(
*
RtAttr
)(
unsafe
.
Pointer
(
&
b
[
0
]))
if
int
(
a
.
Len
)
<
SizeofRtAttr
||
int
(
a
.
Len
)
>
len
(
b
)
{
return
nil
,
nil
,
0
,
EINVAL
}
return
a
,
b
[
SizeofRtAttr
:
],
rtaAlignOf
(
int
(
a
.
Len
)),
nil
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment