1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin dragonfly freebsd netbsd openbsd
15 freebsdConfArch
string // "machine $arch" line in kern.conftxt on freebsd
16 minRoutingSockaddrLen
= rsaAlignOf(0)
19 // Round the length of a raw sockaddr up to align it properly.
20 func rsaAlignOf(salen
int) int {
23 // Darwin kernels require 32-bit aligned access to
24 // routing facilities.
26 } else if netbsd32Bit
{
27 // NetBSD 6 and beyond kernels require 64-bit aligned
28 // access to routing facilities.
30 } else if runtime
.GOOS
== "freebsd" {
31 // In the case of kern.supported_archs="amd64 i386",
32 // we need to know the underlying kernel's
33 // architecture because the alignment for routing
34 // facilities are set at the build time of the kernel.
35 if freebsdConfArch
== "amd64" {
42 return (salen
+ salign
- 1) & ^(salign
- 1)
45 // parseSockaddrLink parses b as a datalink socket address.
46 func parseSockaddrLink(b
[]byte) (*SockaddrDatalink
, error
) {
50 sa
, _
, err
:= parseLinkLayerAddr(b
[4:])
54 rsa
:= (*RawSockaddrDatalink
)(unsafe
.Pointer(&b
[0]))
56 sa
.Family
= rsa
.Family
61 // parseLinkLayerAddr parses b as a datalink socket address in
62 // conventional BSD kernel form.
63 func parseLinkLayerAddr(b
[]byte) (*SockaddrDatalink
, int, error
) {
64 // The encoding looks like the following:
65 // +----------------------------+
67 // +----------------------------+
68 // | Name length (1 octet) |
69 // +----------------------------+
70 // | Address length (1 octet) |
71 // +----------------------------+
72 // | Selector length (1 octet) |
73 // +----------------------------+
74 // | Data (variable) |
75 // +----------------------------+
76 type linkLayerAddr
struct {
82 lla
:= (*linkLayerAddr
)(unsafe
.Pointer(&b
[0]))
83 l
:= 4 + int(lla
.Nlen
) + int(lla
.Alen
) + int(lla
.Slen
)
88 sa
:= &SockaddrDatalink
{Type
: lla
.Type
, Nlen
: lla
.Nlen
, Alen
: lla
.Alen
, Slen
: lla
.Slen
}
89 for i
:= 0; len(sa
.Data
) > i
&& i
< l
-4; i
++ {
90 sa
.Data
[i
] = int8(b
[i
])
92 return sa
, rsaAlignOf(l
), nil
95 // parseSockaddrInet parses b as an internet socket address.
96 func parseSockaddrInet(b
[]byte, family
byte) (Sockaddr
, error
) {
99 if len(b
) < SizeofSockaddrInet4
{
102 rsa
:= (*RawSockaddrAny
)(unsafe
.Pointer(&b
[0]))
103 return anyToSockaddr(rsa
)
105 if len(b
) < SizeofSockaddrInet6
{
108 rsa
:= (*RawSockaddrAny
)(unsafe
.Pointer(&b
[0]))
109 return anyToSockaddr(rsa
)
116 offsetofInet4
= int(unsafe
.Offsetof(RawSockaddrInet4
{}.Addr
))
117 offsetofInet6
= int(unsafe
.Offsetof(RawSockaddrInet6
{}.Addr
))
120 // parseNetworkLayerAddr parses b as an internet socket address in
121 // conventional BSD kernel form.
122 func parseNetworkLayerAddr(b
[]byte, family
byte) (Sockaddr
, error
) {
123 // The encoding looks similar to the NLRI encoding.
124 // +----------------------------+
125 // | Length (1 octet) |
126 // +----------------------------+
127 // | Address prefix (variable) |
128 // +----------------------------+
130 // The differences between the kernel form and the NLRI
133 // - The length field of the kernel form indicates the prefix
134 // length in bytes, not in bits
136 // - In the kernel form, zero value of the length field
137 // doesn't mean 0.0.0.0/0 or ::/0
139 // - The kernel form appends leading bytes to the prefix field
140 // to make the <length, prefix> tuple to be conformed with
141 // the routing messeage boundary
142 l
:= int(rsaAlignOf(int(b
[0])))
146 // Don't reorder case expressions.
147 // The case expressions for IPv6 must come first.
149 case b
[0] == SizeofSockaddrInet6
:
150 sa
:= &SockaddrInet6
{}
151 copy(sa
.Addr
[:], b
[offsetofInet6
:])
153 case family
== AF_INET6
:
154 sa
:= &SockaddrInet6
{}
155 if l
-1 < offsetofInet6
{
156 copy(sa
.Addr
[:], b
[1:l
])
158 copy(sa
.Addr
[:], b
[l
-offsetofInet6
:l
])
161 case b
[0] == SizeofSockaddrInet4
:
162 sa
:= &SockaddrInet4
{}
163 copy(sa
.Addr
[:], b
[offsetofInet4
:])
165 default: // an old fashion, AF_UNSPEC or unknown means AF_INET
166 sa
:= &SockaddrInet4
{}
167 if l
-1 < offsetofInet4
{
168 copy(sa
.Addr
[:], b
[1:l
])
170 copy(sa
.Addr
[:], b
[l
-offsetofInet4
:l
])
176 // RouteRIB returns routing information base, as known as RIB,
177 // which consists of network facility information, states and
179 func RouteRIB(facility
, param
int) ([]byte, error
) {
180 mib
:= []_C_int
{CTL_NET
, AF_ROUTE
, 0, 0, _C_int(facility
), _C_int(param
)}
183 if err
:= sysctl(mib
, nil, &n
, nil, 0); err
!= nil {
189 tab
:= make([]byte, n
)
190 if err
:= sysctl(mib
, &tab
[0], &n
, nil, 0); err
!= nil {
196 // RoutingMessage represents a routing message.
197 type RoutingMessage
interface {
198 sockaddr() ([]Sockaddr
, error
)
201 const anyMessageLen
= int(unsafe
.Sizeof(anyMessage
{}))
203 type anyMessage
struct {
209 // RouteMessage represents a routing message containing routing
211 type RouteMessage
struct {
216 func (m
*RouteMessage
) sockaddr() ([]Sockaddr
, error
) {
217 var sas
[RTAX_MAX
]Sockaddr
219 family
:= uint8(AF_UNSPEC
)
220 for i
:= uint(0); i
< RTAX_MAX
&& len(b
) >= minRoutingSockaddrLen
; i
++ {
221 if m
.Header
.Addrs
&(1<<i
) == 0 {
224 rsa
:= (*RawSockaddr
)(unsafe
.Pointer(&b
[0]))
227 sa
, err
:= parseSockaddrLink(b
)
232 b
= b
[rsaAlignOf(int(rsa
.Len
)):]
233 case AF_INET
, AF_INET6
:
234 sa
, err
:= parseSockaddrInet(b
, rsa
.Family
)
239 b
= b
[rsaAlignOf(int(rsa
.Len
)):]
242 sa
, err
:= parseNetworkLayerAddr(b
, family
)
247 b
= b
[rsaAlignOf(int(b
[0])):]
253 // InterfaceMessage represents a routing message containing
254 // network interface entries.
255 type InterfaceMessage
struct {
260 func (m
*InterfaceMessage
) sockaddr() ([]Sockaddr
, error
) {
261 var sas
[RTAX_MAX
]Sockaddr
262 if m
.Header
.Addrs
&RTA_IFP
== 0 {
265 sa
, err
:= parseSockaddrLink(m
.Data
[:])
273 // InterfaceAddrMessage represents a routing message containing
274 // network interface address entries.
275 type InterfaceAddrMessage
struct {
280 func (m
*InterfaceAddrMessage
) sockaddr() ([]Sockaddr
, error
) {
281 var sas
[RTAX_MAX
]Sockaddr
283 family
:= uint8(AF_UNSPEC
)
284 for i
:= uint(0); i
< RTAX_MAX
&& len(b
) >= minRoutingSockaddrLen
; i
++ {
285 if m
.Header
.Addrs
&(1<<i
) == 0 {
288 rsa
:= (*RawSockaddr
)(unsafe
.Pointer(&b
[0]))
291 sa
, err
:= parseSockaddrLink(b
)
296 b
= b
[rsaAlignOf(int(rsa
.Len
)):]
297 case AF_INET
, AF_INET6
:
298 sa
, err
:= parseSockaddrInet(b
, rsa
.Family
)
303 b
= b
[rsaAlignOf(int(rsa
.Len
)):]
306 sa
, err
:= parseNetworkLayerAddr(b
, family
)
311 b
= b
[rsaAlignOf(int(b
[0])):]
317 // ParseRoutingMessage parses b as routing messages and returns the
318 // slice containing the RoutingMessage interfaces.
319 func ParseRoutingMessage(b
[]byte) (msgs
[]RoutingMessage
, err error
) {
320 nmsgs
, nskips
:= 0, 0
321 for len(b
) >= anyMessageLen
{
323 any
:= (*anyMessage
)(unsafe
.Pointer(&b
[0]))
324 if any
.Version
!= RTM_VERSION
{
328 if m
:= any
.toRoutingMessage(b
); m
== nil {
331 msgs
= append(msgs
, m
)
335 // We failed to parse any of the messages - version mismatch?
336 if nmsgs
!= len(msgs
)+nskips
{
342 // ParseRoutingSockaddr parses msg's payload as raw sockaddrs and
343 // returns the slice containing the Sockaddr interfaces.
344 func ParseRoutingSockaddr(msg RoutingMessage
) ([]Sockaddr
, error
) {
345 sas
, err
:= msg
.sockaddr()