1 // Copyright 2016 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
11 // An Addr represents an address associated with packet routing.
13 // Family returns an address family.
17 // A LinkAddr represents a link-layer address.
18 type LinkAddr struct {
19 Index int // interface index when attached
20 Name string // interface name when attached
21 Addr []byte // link-layer address when attached
24 // Family implements the Family method of Addr interface.
25 func (a *LinkAddr) Family() int { return sysAF_LINK }
27 func (a *LinkAddr) lenAndSpace() (int, int) {
28 l := 8 + len(a.Name) + len(a.Addr)
32 func (a *LinkAddr) marshal(b []byte) (int, error) {
33 l, ll := a.lenAndSpace()
35 return 0, errShortBuffer
37 nlen, alen := len(a.Name), len(a.Addr)
38 if nlen > 255 || alen > 255 {
39 return 0, errInvalidAddr
44 nativeEndian.PutUint16(b[2:4], uint16(a.Index))
49 copy(data[:nlen], a.Addr)
54 copy(data[:alen], a.Name)
60 func parseLinkAddr(b []byte) (Addr, error) {
62 return nil, errInvalidAddr
64 _, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
68 a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
72 // parseKernelLinkAddr parses b as a link-layer address in
73 // conventional BSD kernel form.
74 func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
75 // The encoding looks like the following:
76 // +----------------------------+
78 // +----------------------------+
79 // | Name length (1 octet) |
80 // +----------------------------+
81 // | Address length (1 octet) |
82 // +----------------------------+
83 // | Selector length (1 octet) |
84 // +----------------------------+
85 // | Data (variable) |
86 // +----------------------------+
88 // On some platforms, all-bit-one of length field means "don't
90 nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
100 l := 4 + nlen + alen + slen
102 return 0, nil, errInvalidAddr
108 name = string(data[:nlen])
115 return l, &LinkAddr{Name: name, Addr: addr}, nil
118 // An Inet4Addr represents an internet address for IPv4.
119 type Inet4Addr struct {
120 IP [4]byte // IP address
123 // Family implements the Family method of Addr interface.
124 func (a *Inet4Addr) Family() int { return sysAF_INET }
126 func (a *Inet4Addr) lenAndSpace() (int, int) {
127 return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
130 func (a *Inet4Addr) marshal(b []byte) (int, error) {
131 l, ll := a.lenAndSpace()
133 return 0, errShortBuffer
137 copy(b[4:8], a.IP[:])
141 // An Inet6Addr represents an internet address for IPv6.
142 type Inet6Addr struct {
143 IP [16]byte // IP address
144 ZoneID int // zone identifier
147 // Family implements the Family method of Addr interface.
148 func (a *Inet6Addr) Family() int { return sysAF_INET6 }
150 func (a *Inet6Addr) lenAndSpace() (int, int) {
151 return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
154 func (a *Inet6Addr) marshal(b []byte) (int, error) {
155 l, ll := a.lenAndSpace()
157 return 0, errShortBuffer
161 copy(b[8:24], a.IP[:])
163 nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
168 // parseInetAddr parses b as an internet address for IPv4 or IPv6.
169 func parseInetAddr(af int, b []byte) (Addr, error) {
172 if len(b) < sizeofSockaddrInet {
173 return nil, errInvalidAddr
176 copy(a.IP[:], b[4:8])
179 if len(b) < sizeofSockaddrInet6 {
180 return nil, errInvalidAddr
182 a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
183 copy(a.IP[:], b[8:24])
184 if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
185 // KAME based IPv6 protocol stack usually
186 // embeds the interface index in the
187 // interface-local or link-local address as
188 // the kernel-internal form.
189 id := int(bigEndian.Uint16(a.IP[2:4]))
192 a.IP[2], a.IP[3] = 0, 0
197 return nil, errInvalidAddr
201 // parseKernelInetAddr parses b as an internet address in conventional
203 func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
204 // The encoding looks similar to the NLRI encoding.
205 // +----------------------------+
206 // | Length (1 octet) |
207 // +----------------------------+
208 // | Address prefix (variable) |
209 // +----------------------------+
211 // The differences between the kernel form and the NLRI
214 // - The length field of the kernel form indicates the prefix
215 // length in bytes, not in bits
217 // - In the kernel form, zero value of the length field
218 // doesn't mean 0.0.0.0/0 or ::/0
220 // - The kernel form appends leading bytes to the prefix field
221 // to make the <length, prefix> tuple to be conformed with
222 // the routing message boundary
224 if runtime.GOOS == "darwin" {
225 // On Darwn, an address in the kernel form is also
226 // used as a message filler.
227 if l == 0 || len(b) > roundup(l) {
234 return 0, nil, errInvalidAddr
236 // Don't reorder case expressions.
237 // The case expressions for IPv6 must come first.
239 off4 = 4 // offset of in_addr
240 off6 = 8 // offset of in6_addr
243 case b[0] == sizeofSockaddrInet6:
245 copy(a.IP[:], b[off6:off6+16])
246 return int(b[0]), a, nil
247 case af == sysAF_INET6:
250 copy(a.IP[:], b[1:l])
252 copy(a.IP[:], b[l-off6:l])
254 return int(b[0]), a, nil
255 case b[0] == sizeofSockaddrInet:
257 copy(a.IP[:], b[off4:off4+4])
258 return int(b[0]), a, nil
259 default: // an old fashion, AF_UNSPEC or unknown means AF_INET
262 copy(a.IP[:], b[1:l])
264 copy(a.IP[:], b[l-off4:l])
266 return int(b[0]), a, nil
270 // A DefaultAddr represents an address of various operating
271 // system-specific features.
272 type DefaultAddr struct {
274 Raw []byte // raw format of address
277 // Family implements the Family method of Addr interface.
278 func (a *DefaultAddr) Family() int { return a.af }
280 func (a *DefaultAddr) lenAndSpace() (int, int) {
285 func (a *DefaultAddr) marshal(b []byte) (int, error) {
286 l, ll := a.lenAndSpace()
288 return 0, errShortBuffer
291 return 0, errInvalidAddr
298 func parseDefaultAddr(b []byte) (Addr, error) {
299 if len(b) < 2 || len(b) < int(b[0]) {
300 return nil, errInvalidAddr
302 a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
306 func addrsSpace(as []Addr) int {
308 for _, a := range as {
309 switch a := a.(type) {
311 _, ll := a.lenAndSpace()
314 _, ll := a.lenAndSpace()
317 _, ll := a.lenAndSpace()
320 _, ll := a.lenAndSpace()
327 // marshalAddrs marshals as and returns a bitmap indicating which
328 // address is stored in b.
329 func marshalAddrs(b []byte, as []Addr) (uint, error) {
331 for i, a := range as {
332 switch a := a.(type) {
334 l, err := a.marshal(b)
339 attrs |= 1 << uint(i)
341 l, err := a.marshal(b)
346 attrs |= 1 << uint(i)
348 l, err := a.marshal(b)
353 attrs |= 1 << uint(i)
355 l, err := a.marshal(b)
360 attrs |= 1 << uint(i)
366 func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
367 var as [sysRTAX_MAX]Addr
368 af := int(sysAF_UNSPEC)
369 for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
370 if attrs&(1<<i) == 0 {
373 if i <= sysRTAX_BRD {
376 a, err := parseLinkAddr(b)
381 l := roundup(int(b[0]))
383 return nil, errMessageTooShort
386 case sysAF_INET, sysAF_INET6:
388 a, err := parseInetAddr(af, b)
393 l := roundup(int(b[0]))
395 return nil, errMessageTooShort
399 l, a, err := fn(af, b)
412 a, err := parseDefaultAddr(b)
417 l := roundup(int(b[0]))
419 return nil, errMessageTooShort