route_bsd.go 9.1 KB

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