Brad Fitzpatrick | 5194744 | 2016-03-01 22:57:46 +0000 | [diff] [blame] | 1 | // Copyright 2011 The Go Authors. All rights reserved. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Joel Sing | 8f3f4c9 | 2013-08-24 01:51:25 +1000 | [diff] [blame] | 5 | // +build darwin dragonfly freebsd netbsd openbsd |
Russ Cox | 2715956 | 2011-09-15 16:48:57 -0400 | [diff] [blame] | 6 | |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 7 | package syscall |
| 8 | |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 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 | ) |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 18 | |
Robert Hencke | 3fbd478 | 2011-05-30 18:02:59 +1000 | [diff] [blame] | 19 | // Round the length of a raw sockaddr up to align it properly. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 20 | func rsaAlignOf(salen int) int { |
| 21 | salign := sizeofPtr |
Mikio Hara | 9a79472 | 2013-08-25 08:44:31 +0900 | [diff] [blame] | 22 | if darwin64Bit { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 23 | // Darwin kernels require 32-bit aligned access to |
| 24 | // routing facilities. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 25 | salign = 4 |
Mikio Hara | 9a79472 | 2013-08-25 08:44:31 +0900 | [diff] [blame] | 26 | } else if netbsd32Bit { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 27 | // NetBSD 6 and beyond kernels require 64-bit aligned |
| 28 | // access to routing facilities. |
Mikio Hara | 9a79472 | 2013-08-25 08:44:31 +0900 | [diff] [blame] | 29 | salign = 8 |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 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 | } |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 38 | } |
| 39 | if salen == 0 { |
| 40 | return salign |
| 41 | } |
| 42 | return (salen + salign - 1) & ^(salign - 1) |
| 43 | } |
| 44 | |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 45 | // parseSockaddrLink parses b as a datalink socket address. |
| 46 | func parseSockaddrLink(b []byte) (*SockaddrDatalink, error) { |
Mikio Hara | 707b619 | 2015-09-24 15:23:26 +0900 | [diff] [blame] | 47 | if len(b) < 8 { |
| 48 | return nil, EINVAL |
| 49 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 50 | sa, _, err := parseLinkLayerAddr(b[4:]) |
| 51 | if err != nil { |
| 52 | return nil, err |
| 53 | } |
| 54 | rsa := (*RawSockaddrDatalink)(unsafe.Pointer(&b[0])) |
| 55 | sa.Len = rsa.Len |
| 56 | sa.Family = rsa.Family |
| 57 | sa.Index = rsa.Index |
| 58 | return sa, nil |
| 59 | } |
| 60 | |
| 61 | // parseLinkLayerAddr parses b as a datalink socket address in |
| 62 | // conventional BSD kernel form. |
| 63 | func parseLinkLayerAddr(b []byte) (*SockaddrDatalink, int, error) { |
Ainar Garipov | 7f9f70e | 2015-06-11 16:49:38 +0300 | [diff] [blame] | 64 | // The encoding looks like the following: |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 65 | // +----------------------------+ |
| 66 | // | Type (1 octet) | |
| 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 { |
| 77 | Type byte |
| 78 | Nlen byte |
| 79 | Alen byte |
| 80 | Slen byte |
| 81 | } |
| 82 | lla := (*linkLayerAddr)(unsafe.Pointer(&b[0])) |
Mikio Hara | 707b619 | 2015-09-24 15:23:26 +0900 | [diff] [blame] | 83 | l := 4 + int(lla.Nlen) + int(lla.Alen) + int(lla.Slen) |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 84 | if len(b) < l { |
| 85 | return nil, 0, EINVAL |
| 86 | } |
| 87 | b = b[4:] |
| 88 | sa := &SockaddrDatalink{Type: lla.Type, Nlen: lla.Nlen, Alen: lla.Alen, Slen: lla.Slen} |
Mikio Hara | 707b619 | 2015-09-24 15:23:26 +0900 | [diff] [blame] | 89 | for i := 0; len(sa.Data) > i && i < l-4; i++ { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 90 | sa.Data[i] = int8(b[i]) |
| 91 | } |
Mikio Hara | 707b619 | 2015-09-24 15:23:26 +0900 | [diff] [blame] | 92 | return sa, rsaAlignOf(l), nil |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | // parseSockaddrInet parses b as an internet socket address. |
| 96 | func parseSockaddrInet(b []byte, family byte) (Sockaddr, error) { |
| 97 | switch family { |
| 98 | case AF_INET: |
| 99 | if len(b) < SizeofSockaddrInet4 { |
| 100 | return nil, EINVAL |
| 101 | } |
| 102 | rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0])) |
| 103 | return anyToSockaddr(rsa) |
| 104 | case AF_INET6: |
| 105 | if len(b) < SizeofSockaddrInet6 { |
| 106 | return nil, EINVAL |
| 107 | } |
| 108 | rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0])) |
| 109 | return anyToSockaddr(rsa) |
| 110 | default: |
| 111 | return nil, EINVAL |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | const ( |
| 116 | offsetofInet4 = int(unsafe.Offsetof(RawSockaddrInet4{}.Addr)) |
| 117 | offsetofInet6 = int(unsafe.Offsetof(RawSockaddrInet6{}.Addr)) |
| 118 | ) |
| 119 | |
| 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 | // +----------------------------+ |
| 129 | // |
| 130 | // The differences between the kernel form and the NLRI |
| 131 | // encoding are: |
| 132 | // |
| 133 | // - The length field of the kernel form indicates the prefix |
| 134 | // length in bytes, not in bits |
| 135 | // |
| 136 | // - In the kernel form, zero value of the length field |
| 137 | // doesn't mean 0.0.0.0/0 or ::/0 |
| 138 | // |
| 139 | // - The kernel form appends leading bytes to the prefix field |
| 140 | // to make the <length, prefix> tuple to be conformed with |
Martin Möhrmann | fdd0179 | 2016-02-24 11:55:20 +0100 | [diff] [blame] | 141 | // the routing message boundary |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 142 | l := int(rsaAlignOf(int(b[0]))) |
| 143 | if len(b) < l { |
| 144 | return nil, EINVAL |
| 145 | } |
Mikio Hara | 59cc5a1 | 2015-03-01 23:58:28 +0900 | [diff] [blame] | 146 | // Don't reorder case expressions. |
| 147 | // The case expressions for IPv6 must come first. |
| 148 | switch { |
| 149 | case b[0] == SizeofSockaddrInet6: |
| 150 | sa := &SockaddrInet6{} |
| 151 | copy(sa.Addr[:], b[offsetofInet6:]) |
| 152 | return sa, nil |
| 153 | case family == AF_INET6: |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 154 | sa := &SockaddrInet6{} |
| 155 | if l-1 < offsetofInet6 { |
| 156 | copy(sa.Addr[:], b[1:l]) |
| 157 | } else { |
| 158 | copy(sa.Addr[:], b[l-offsetofInet6:l]) |
| 159 | } |
| 160 | return sa, nil |
Mikio Hara | 59cc5a1 | 2015-03-01 23:58:28 +0900 | [diff] [blame] | 161 | case b[0] == SizeofSockaddrInet4: |
| 162 | sa := &SockaddrInet4{} |
| 163 | copy(sa.Addr[:], b[offsetofInet4:]) |
| 164 | return sa, nil |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 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]) |
| 169 | } else { |
| 170 | copy(sa.Addr[:], b[l-offsetofInet4:l]) |
| 171 | } |
| 172 | return sa, nil |
| 173 | } |
| 174 | } |
| 175 | |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 176 | // RouteRIB returns routing information base, as known as RIB, |
| 177 | // which consists of network facility information, states and |
| 178 | // parameters. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 179 | // |
| 180 | // Deprecated: Use golang.org/x/net/route instead. |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 181 | func RouteRIB(facility, param int) ([]byte, error) { |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 182 | mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)} |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 183 | // Find size. |
| 184 | n := uintptr(0) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 185 | if err := sysctl(mib, nil, &n, nil, 0); err != nil { |
| 186 | return nil, err |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 187 | } |
| 188 | if n == 0 { |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 189 | return nil, nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 190 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 191 | tab := make([]byte, n) |
| 192 | if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil { |
| 193 | return nil, err |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 194 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 195 | return tab[:n], nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 196 | } |
| 197 | |
| 198 | // RoutingMessage represents a routing message. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 199 | // |
| 200 | // Deprecated: Use golang.org/x/net/route instead. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 201 | type RoutingMessage interface { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 202 | sockaddr() ([]Sockaddr, error) |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 203 | } |
| 204 | |
Russ Cox | 61f4ec1 | 2011-06-17 17:07:21 -0400 | [diff] [blame] | 205 | const anyMessageLen = int(unsafe.Sizeof(anyMessage{})) |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 206 | |
| 207 | type anyMessage struct { |
| 208 | Msglen uint16 |
| 209 | Version uint8 |
| 210 | Type uint8 |
| 211 | } |
| 212 | |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 213 | // RouteMessage represents a routing message containing routing |
| 214 | // entries. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 215 | // |
| 216 | // Deprecated: Use golang.org/x/net/route instead. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 217 | type RouteMessage struct { |
| 218 | Header RtMsghdr |
| 219 | Data []byte |
| 220 | } |
| 221 | |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 222 | func (m *RouteMessage) sockaddr() ([]Sockaddr, error) { |
| 223 | var sas [RTAX_MAX]Sockaddr |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 224 | b := m.Data[:] |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 225 | family := uint8(AF_UNSPEC) |
| 226 | for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ { |
| 227 | if m.Header.Addrs&(1<<i) == 0 { |
Mikio Hara | 0c6581c | 2011-08-31 13:05:49 -0400 | [diff] [blame] | 228 | continue |
| 229 | } |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 230 | rsa := (*RawSockaddr)(unsafe.Pointer(&b[0])) |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 231 | switch rsa.Family { |
| 232 | case AF_LINK: |
| 233 | sa, err := parseSockaddrLink(b) |
Mikio Hara | 8361056 | 2011-12-21 21:39:00 +0900 | [diff] [blame] | 234 | if err != nil { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 235 | return nil, err |
Mikio Hara | 0c6581c | 2011-08-31 13:05:49 -0400 | [diff] [blame] | 236 | } |
| 237 | sas[i] = sa |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 238 | b = b[rsaAlignOf(int(rsa.Len)):] |
| 239 | case AF_INET, AF_INET6: |
| 240 | sa, err := parseSockaddrInet(b, rsa.Family) |
| 241 | if err != nil { |
| 242 | return nil, err |
Mikio Hara | 0c6581c | 2011-08-31 13:05:49 -0400 | [diff] [blame] | 243 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 244 | sas[i] = sa |
| 245 | b = b[rsaAlignOf(int(rsa.Len)):] |
| 246 | family = rsa.Family |
| 247 | default: |
| 248 | sa, err := parseNetworkLayerAddr(b, family) |
| 249 | if err != nil { |
| 250 | return nil, err |
| 251 | } |
| 252 | sas[i] = sa |
| 253 | b = b[rsaAlignOf(int(b[0])):] |
Mikio Hara | 0c6581c | 2011-08-31 13:05:49 -0400 | [diff] [blame] | 254 | } |
Mikio Hara | 0c6581c | 2011-08-31 13:05:49 -0400 | [diff] [blame] | 255 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 256 | return sas[:], nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 257 | } |
| 258 | |
| 259 | // InterfaceMessage represents a routing message containing |
| 260 | // network interface entries. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 261 | // |
| 262 | // Deprecated: Use golang.org/x/net/route instead. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 263 | type InterfaceMessage struct { |
| 264 | Header IfMsghdr |
| 265 | Data []byte |
| 266 | } |
| 267 | |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 268 | func (m *InterfaceMessage) sockaddr() ([]Sockaddr, error) { |
| 269 | var sas [RTAX_MAX]Sockaddr |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 270 | if m.Header.Addrs&RTA_IFP == 0 { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 271 | return nil, nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 272 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 273 | sa, err := parseSockaddrLink(m.Data[:]) |
Mikio Hara | 8361056 | 2011-12-21 21:39:00 +0900 | [diff] [blame] | 274 | if err != nil { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 275 | return nil, err |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 276 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 277 | sas[RTAX_IFP] = sa |
| 278 | return sas[:], nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 279 | } |
| 280 | |
| 281 | // InterfaceAddrMessage represents a routing message containing |
| 282 | // network interface address entries. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 283 | // |
| 284 | // Deprecated: Use golang.org/x/net/route instead. |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 285 | type InterfaceAddrMessage struct { |
| 286 | Header IfaMsghdr |
| 287 | Data []byte |
| 288 | } |
| 289 | |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 290 | func (m *InterfaceAddrMessage) sockaddr() ([]Sockaddr, error) { |
| 291 | var sas [RTAX_MAX]Sockaddr |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 292 | b := m.Data[:] |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 293 | family := uint8(AF_UNSPEC) |
| 294 | for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ { |
Russ Cox | 96e9e81 | 2014-10-28 11:35:00 -0400 | [diff] [blame] | 295 | if m.Header.Addrs&(1<<i) == 0 { |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 296 | continue |
| 297 | } |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 298 | rsa := (*RawSockaddr)(unsafe.Pointer(&b[0])) |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 299 | switch rsa.Family { |
| 300 | case AF_LINK: |
| 301 | sa, err := parseSockaddrLink(b) |
Mikio Hara | 8361056 | 2011-12-21 21:39:00 +0900 | [diff] [blame] | 302 | if err != nil { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 303 | return nil, err |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 304 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 305 | sas[i] = sa |
| 306 | b = b[rsaAlignOf(int(rsa.Len)):] |
| 307 | case AF_INET, AF_INET6: |
| 308 | sa, err := parseSockaddrInet(b, rsa.Family) |
Mikio Hara | 8361056 | 2011-12-21 21:39:00 +0900 | [diff] [blame] | 309 | if err != nil { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 310 | return nil, err |
Mikio Hara | 8361056 | 2011-12-21 21:39:00 +0900 | [diff] [blame] | 311 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 312 | sas[i] = sa |
| 313 | b = b[rsaAlignOf(int(rsa.Len)):] |
| 314 | family = rsa.Family |
| 315 | default: |
| 316 | sa, err := parseNetworkLayerAddr(b, family) |
| 317 | if err != nil { |
| 318 | return nil, err |
| 319 | } |
| 320 | sas[i] = sa |
| 321 | b = b[rsaAlignOf(int(b[0])):] |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 322 | } |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 323 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 324 | return sas[:], nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 325 | } |
| 326 | |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 327 | // ParseRoutingMessage parses b as routing messages and returns the |
| 328 | // slice containing the RoutingMessage interfaces. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 329 | // |
| 330 | // Deprecated: Use golang.org/x/net/route instead. |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 331 | func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 332 | nmsgs, nskips := 0, 0 |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 333 | for len(b) >= anyMessageLen { |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 334 | nmsgs++ |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 335 | any := (*anyMessage)(unsafe.Pointer(&b[0])) |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 336 | if any.Version != RTM_VERSION { |
Joel Sing | 517e49e | 2013-12-11 00:03:46 +1100 | [diff] [blame] | 337 | b = b[any.Msglen:] |
| 338 | continue |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 339 | } |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 340 | if m := any.toRoutingMessage(b); m == nil { |
| 341 | nskips++ |
| 342 | } else { |
| 343 | msgs = append(msgs, m) |
| 344 | } |
Mikio Hara | c5f5df4 | 2013-02-24 12:36:44 +0900 | [diff] [blame] | 345 | b = b[any.Msglen:] |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 346 | } |
Joel Sing | 517e49e | 2013-12-11 00:03:46 +1100 | [diff] [blame] | 347 | // We failed to parse any of the messages - version mismatch? |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 348 | if nmsgs != len(msgs)+nskips { |
Joel Sing | 517e49e | 2013-12-11 00:03:46 +1100 | [diff] [blame] | 349 | return nil, EINVAL |
| 350 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 351 | return msgs, nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 352 | } |
| 353 | |
Yann Kerhervé | 5c24832 | 2015-12-04 10:07:44 -0800 | [diff] [blame] | 354 | // ParseRoutingSockaddr parses msg's payload as raw sockaddrs and |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 355 | // returns the slice containing the Sockaddr interfaces. |
Mikio Hara | 6d66819 | 2016-04-23 22:36:41 +0900 | [diff] [blame] | 356 | // |
| 357 | // Deprecated: Use golang.org/x/net/route instead. |
Mikio Hara | 69275ee | 2015-02-10 12:24:11 +0900 | [diff] [blame] | 358 | func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { |
| 359 | sas, err := msg.sockaddr() |
| 360 | if err != nil { |
| 361 | return nil, err |
| 362 | } |
| 363 | return sas, nil |
Mikio Hara | 12376c9 | 2011-05-26 20:02:03 -0400 | [diff] [blame] | 364 | } |