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. 4 5 // +build darwin dragonfly freebsd netbsd openbsd 6 7 package syscall 8 9 import ( 10 "runtime" 11 "unsafe" 12 ) 13 14 var ( 15 freebsdConfArch string // "machine $arch" line in kern.conftxt on freebsd 16 minRoutingSockaddrLen = rsaAlignOf(0) 17 ) 18 19 // Round the length of a raw sockaddr up to align it properly. 20 func rsaAlignOf(salen int) int { 21 salign := sizeofPtr 22 if darwin64Bit { 23 // Darwin kernels require 32-bit aligned access to 24 // routing facilities. 25 salign = 4 26 } else if netbsd32Bit { 27 // NetBSD 6 and beyond kernels require 64-bit aligned 28 // access to routing facilities. 29 salign = 8 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" { 36 salign = 8 37 } 38 } 39 if salen == 0 { 40 return salign 41 } 42 return (salen + salign - 1) & ^(salign - 1) 43 } 44 45 // parseSockaddrLink parses b as a datalink socket address. 46 func parseSockaddrLink(b []byte) (*SockaddrDatalink, error) { 47 sa, _, err := parseLinkLayerAddr(b[4:]) 48 if err != nil { 49 return nil, err 50 } 51 rsa := (*RawSockaddrDatalink)(unsafe.Pointer(&b[0])) 52 sa.Len = rsa.Len 53 sa.Family = rsa.Family 54 sa.Index = rsa.Index 55 return sa, nil 56 } 57 58 // parseLinkLayerAddr parses b as a datalink socket address in 59 // conventional BSD kernel form. 60 func parseLinkLayerAddr(b []byte) (*SockaddrDatalink, int, error) { 61 // The encoding looks like the following: 62 // +----------------------------+ 63 // | Type (1 octet) | 64 // +----------------------------+ 65 // | Name length (1 octet) | 66 // +----------------------------+ 67 // | Address length (1 octet) | 68 // +----------------------------+ 69 // | Selector length (1 octet) | 70 // +----------------------------+ 71 // | Data (variable) | 72 // +----------------------------+ 73 type linkLayerAddr struct { 74 Type byte 75 Nlen byte 76 Alen byte 77 Slen byte 78 } 79 lla := (*linkLayerAddr)(unsafe.Pointer(&b[0])) 80 l := rsaAlignOf(int(4 + lla.Nlen + lla.Alen + lla.Slen)) 81 if len(b) < l { 82 return nil, 0, EINVAL 83 } 84 b = b[4:] 85 sa := &SockaddrDatalink{Type: lla.Type, Nlen: lla.Nlen, Alen: lla.Alen, Slen: lla.Slen} 86 for i := 0; len(sa.Data) > i && i < int(lla.Nlen+lla.Alen+lla.Slen); i++ { 87 sa.Data[i] = int8(b[i]) 88 } 89 return sa, l, nil 90 } 91 92 // parseSockaddrInet parses b as an internet socket address. 93 func parseSockaddrInet(b []byte, family byte) (Sockaddr, error) { 94 switch family { 95 case AF_INET: 96 if len(b) < SizeofSockaddrInet4 { 97 return nil, EINVAL 98 } 99 rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0])) 100 return anyToSockaddr(rsa) 101 case AF_INET6: 102 if len(b) < SizeofSockaddrInet6 { 103 return nil, EINVAL 104 } 105 rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0])) 106 return anyToSockaddr(rsa) 107 default: 108 return nil, EINVAL 109 } 110 } 111 112 const ( 113 offsetofInet4 = int(unsafe.Offsetof(RawSockaddrInet4{}.Addr)) 114 offsetofInet6 = int(unsafe.Offsetof(RawSockaddrInet6{}.Addr)) 115 ) 116 117 // parseNetworkLayerAddr parses b as an internet socket address in 118 // conventional BSD kernel form. 119 func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) { 120 // The encoding looks similar to the NLRI encoding. 121 // +----------------------------+ 122 // | Length (1 octet) | 123 // +----------------------------+ 124 // | Address prefix (variable) | 125 // +----------------------------+ 126 // 127 // The differences between the kernel form and the NLRI 128 // encoding are: 129 // 130 // - The length field of the kernel form indicates the prefix 131 // length in bytes, not in bits 132 // 133 // - In the kernel form, zero value of the length field 134 // doesn't mean 0.0.0.0/0 or ::/0 135 // 136 // - The kernel form appends leading bytes to the prefix field 137 // to make the <length, prefix> tuple to be conformed with 138 // the routing messeage boundary 139 l := int(rsaAlignOf(int(b[0]))) 140 if len(b) < l { 141 return nil, EINVAL 142 } 143 // Don't reorder case expressions. 144 // The case expressions for IPv6 must come first. 145 switch { 146 case b[0] == SizeofSockaddrInet6: 147 sa := &SockaddrInet6{} 148 copy(sa.Addr[:], b[offsetofInet6:]) 149 return sa, nil 150 case family == AF_INET6: 151 sa := &SockaddrInet6{} 152 if l-1 < offsetofInet6 { 153 copy(sa.Addr[:], b[1:l]) 154 } else { 155 copy(sa.Addr[:], b[l-offsetofInet6:l]) 156 } 157 return sa, nil 158 case b[0] == SizeofSockaddrInet4: 159 sa := &SockaddrInet4{} 160 copy(sa.Addr[:], b[offsetofInet4:]) 161 return sa, nil 162 default: // an old fashion, AF_UNSPEC or unknown means AF_INET 163 sa := &SockaddrInet4{} 164 if l-1 < offsetofInet4 { 165 copy(sa.Addr[:], b[1:l]) 166 } else { 167 copy(sa.Addr[:], b[l-offsetofInet4:l]) 168 } 169 return sa, nil 170 } 171 } 172 173 // RouteRIB returns routing information base, as known as RIB, 174 // which consists of network facility information, states and 175 // parameters. 176 func RouteRIB(facility, param int) ([]byte, error) { 177 mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)} 178 // Find size. 179 n := uintptr(0) 180 if err := sysctl(mib, nil, &n, nil, 0); err != nil { 181 return nil, err 182 } 183 if n == 0 { 184 return nil, nil 185 } 186 tab := make([]byte, n) 187 if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil { 188 return nil, err 189 } 190 return tab[:n], nil 191 } 192 193 // RoutingMessage represents a routing message. 194 type RoutingMessage interface { 195 sockaddr() ([]Sockaddr, error) 196 } 197 198 const anyMessageLen = int(unsafe.Sizeof(anyMessage{})) 199 200 type anyMessage struct { 201 Msglen uint16 202 Version uint8 203 Type uint8 204 } 205 206 // RouteMessage represents a routing message containing routing 207 // entries. 208 type RouteMessage struct { 209 Header RtMsghdr 210 Data []byte 211 } 212 213 func (m *RouteMessage) sockaddr() ([]Sockaddr, error) { 214 var sas [RTAX_MAX]Sockaddr 215 b := m.Data[:] 216 family := uint8(AF_UNSPEC) 217 for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ { 218 if m.Header.Addrs&(1<<i) == 0 { 219 continue 220 } 221 rsa := (*RawSockaddr)(unsafe.Pointer(&b[0])) 222 switch rsa.Family { 223 case AF_LINK: 224 sa, err := parseSockaddrLink(b) 225 if err != nil { 226 return nil, err 227 } 228 sas[i] = sa 229 b = b[rsaAlignOf(int(rsa.Len)):] 230 case AF_INET, AF_INET6: 231 sa, err := parseSockaddrInet(b, rsa.Family) 232 if err != nil { 233 return nil, err 234 } 235 sas[i] = sa 236 b = b[rsaAlignOf(int(rsa.Len)):] 237 family = rsa.Family 238 default: 239 sa, err := parseNetworkLayerAddr(b, family) 240 if err != nil { 241 return nil, err 242 } 243 sas[i] = sa 244 b = b[rsaAlignOf(int(b[0])):] 245 } 246 } 247 return sas[:], nil 248 } 249 250 // InterfaceMessage represents a routing message containing 251 // network interface entries. 252 type InterfaceMessage struct { 253 Header IfMsghdr 254 Data []byte 255 } 256 257 func (m *InterfaceMessage) sockaddr() ([]Sockaddr, error) { 258 var sas [RTAX_MAX]Sockaddr 259 if m.Header.Addrs&RTA_IFP == 0 { 260 return nil, nil 261 } 262 sa, err := parseSockaddrLink(m.Data[:]) 263 if err != nil { 264 return nil, err 265 } 266 sas[RTAX_IFP] = sa 267 return sas[:], nil 268 } 269 270 // InterfaceAddrMessage represents a routing message containing 271 // network interface address entries. 272 type InterfaceAddrMessage struct { 273 Header IfaMsghdr 274 Data []byte 275 } 276 277 func (m *InterfaceAddrMessage) sockaddr() ([]Sockaddr, error) { 278 var sas [RTAX_MAX]Sockaddr 279 b := m.Data[:] 280 family := uint8(AF_UNSPEC) 281 for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ { 282 if m.Header.Addrs&(1<<i) == 0 { 283 continue 284 } 285 rsa := (*RawSockaddr)(unsafe.Pointer(&b[0])) 286 switch rsa.Family { 287 case AF_LINK: 288 sa, err := parseSockaddrLink(b) 289 if err != nil { 290 return nil, err 291 } 292 sas[i] = sa 293 b = b[rsaAlignOf(int(rsa.Len)):] 294 case AF_INET, AF_INET6: 295 sa, err := parseSockaddrInet(b, rsa.Family) 296 if err != nil { 297 return nil, err 298 } 299 sas[i] = sa 300 b = b[rsaAlignOf(int(rsa.Len)):] 301 family = rsa.Family 302 default: 303 sa, err := parseNetworkLayerAddr(b, family) 304 if err != nil { 305 return nil, err 306 } 307 sas[i] = sa 308 b = b[rsaAlignOf(int(b[0])):] 309 } 310 } 311 return sas[:], nil 312 } 313 314 // ParseRoutingMessage parses b as routing messages and returns the 315 // slice containing the RoutingMessage interfaces. 316 func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) { 317 nmsgs, nskips := 0, 0 318 for len(b) >= anyMessageLen { 319 nmsgs++ 320 any := (*anyMessage)(unsafe.Pointer(&b[0])) 321 if any.Version != RTM_VERSION { 322 b = b[any.Msglen:] 323 continue 324 } 325 if m := any.toRoutingMessage(b); m == nil { 326 nskips++ 327 } else { 328 msgs = append(msgs, m) 329 } 330 b = b[any.Msglen:] 331 } 332 // We failed to parse any of the messages - version mismatch? 333 if nmsgs != len(msgs)+nskips { 334 return nil, EINVAL 335 } 336 return msgs, nil 337 } 338 339 // ParseRoutingMessage parses msg's payload as raw sockaddrs and 340 // returns the slice containing the Sockaddr interfaces. 341 func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { 342 sas, err := msg.sockaddr() 343 if err != nil { 344 return nil, err 345 } 346 return sas, nil 347 } 348