Home | History | Annotate | Download | only in route
      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.
      4 
      5 // +build darwin dragonfly freebsd netbsd openbsd
      6 
      7 package route
      8 
      9 import "runtime"
     10 
     11 // An Addr represents an address associated with packet routing.
     12 type Addr interface {
     13 	// Family returns an address family.
     14 	Family() int
     15 }
     16 
     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
     22 }
     23 
     24 // Family implements the Family method of Addr interface.
     25 func (a *LinkAddr) Family() int { return sysAF_LINK }
     26 
     27 func parseLinkAddr(b []byte) (Addr, error) {
     28 	if len(b) < 8 {
     29 		return nil, errInvalidAddr
     30 	}
     31 	_, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
     32 	if err != nil {
     33 		return nil, err
     34 	}
     35 	a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
     36 	return a, nil
     37 }
     38 
     39 // parseKernelLinkAddr parses b as a link-layer address in
     40 // conventional BSD kernel form.
     41 func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
     42 	// The encoding looks like the following:
     43 	// +----------------------------+
     44 	// | Type             (1 octet) |
     45 	// +----------------------------+
     46 	// | Name length      (1 octet) |
     47 	// +----------------------------+
     48 	// | Address length   (1 octet) |
     49 	// +----------------------------+
     50 	// | Selector length  (1 octet) |
     51 	// +----------------------------+
     52 	// | Data            (variable) |
     53 	// +----------------------------+
     54 	//
     55 	// On some platforms, all-bit-one of length field means "don't
     56 	// care".
     57 	nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
     58 	if nlen == 0xff {
     59 		nlen = 0
     60 	}
     61 	if alen == 0xff {
     62 		alen = 0
     63 	}
     64 	if slen == 0xff {
     65 		slen = 0
     66 	}
     67 	l := 4 + nlen + alen + slen
     68 	if len(b) < l {
     69 		return 0, nil, errInvalidAddr
     70 	}
     71 	data := b[4:]
     72 	var name string
     73 	var addr []byte
     74 	if nlen > 0 {
     75 		name = string(data[:nlen])
     76 		data = data[nlen:]
     77 	}
     78 	if alen > 0 {
     79 		addr = data[:alen]
     80 		data = data[alen:]
     81 	}
     82 	return l, &LinkAddr{Name: name, Addr: addr}, nil
     83 }
     84 
     85 // An Inet4Addr represents an internet address for IPv4.
     86 type Inet4Addr struct {
     87 	IP [4]byte // IP address
     88 }
     89 
     90 // Family implements the Family method of Addr interface.
     91 func (a *Inet4Addr) Family() int { return sysAF_INET }
     92 
     93 // An Inet6Addr represents an internet address for IPv6.
     94 type Inet6Addr struct {
     95 	IP     [16]byte // IP address
     96 	ZoneID int      // zone identifier
     97 }
     98 
     99 // Family implements the Family method of Addr interface.
    100 func (a *Inet6Addr) Family() int { return sysAF_INET6 }
    101 
    102 // parseInetAddr parses b as an internet address for IPv4 or IPv6.
    103 func parseInetAddr(af int, b []byte) (Addr, error) {
    104 	switch af {
    105 	case sysAF_INET:
    106 		if len(b) < 16 {
    107 			return nil, errInvalidAddr
    108 		}
    109 		a := &Inet4Addr{}
    110 		copy(a.IP[:], b[4:8])
    111 		return a, nil
    112 	case sysAF_INET6:
    113 		if len(b) < 28 {
    114 			return nil, errInvalidAddr
    115 		}
    116 		a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
    117 		copy(a.IP[:], b[8:24])
    118 		if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
    119 			// KAME based IPv6 protocol stack usually
    120 			// embeds the interface index in the
    121 			// interface-local or link-local address as
    122 			// the kernel-internal form.
    123 			id := int(bigEndian.Uint16(a.IP[2:4]))
    124 			if id != 0 {
    125 				a.ZoneID = id
    126 				a.IP[2], a.IP[3] = 0, 0
    127 			}
    128 		}
    129 		return a, nil
    130 	default:
    131 		return nil, errInvalidAddr
    132 	}
    133 }
    134 
    135 // parseKernelInetAddr parses b as an internet address in conventional
    136 // BSD kernel form.
    137 func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
    138 	// The encoding looks similar to the NLRI encoding.
    139 	// +----------------------------+
    140 	// | Length           (1 octet) |
    141 	// +----------------------------+
    142 	// | Address prefix  (variable) |
    143 	// +----------------------------+
    144 	//
    145 	// The differences between the kernel form and the NLRI
    146 	// encoding are:
    147 	//
    148 	// - The length field of the kernel form indicates the prefix
    149 	//   length in bytes, not in bits
    150 	//
    151 	// - In the kernel form, zero value of the length field
    152 	//   doesn't mean 0.0.0.0/0 or ::/0
    153 	//
    154 	// - The kernel form appends leading bytes to the prefix field
    155 	//   to make the <length, prefix> tuple to be conformed with
    156 	//   the routing message boundary
    157 	l := int(b[0])
    158 	if runtime.GOOS == "darwin" {
    159 		// On Darwn, an address in the kernel form is also
    160 		// used as a message filler.
    161 		if l == 0 || len(b) > roundup(l) {
    162 			l = roundup(l)
    163 		}
    164 	} else {
    165 		l = roundup(l)
    166 	}
    167 	if len(b) < l {
    168 		return 0, nil, errInvalidAddr
    169 	}
    170 	// Don't reorder case expressions.
    171 	// The case expressions for IPv6 must come first.
    172 	const (
    173 		off4 = 4 // offset of in_addr
    174 		off6 = 8 // offset of in6_addr
    175 	)
    176 	switch {
    177 	case b[0] == 28: // size of sockaddr_in6
    178 		a := &Inet6Addr{}
    179 		copy(a.IP[:], b[off6:off6+16])
    180 		return int(b[0]), a, nil
    181 	case af == sysAF_INET6:
    182 		a := &Inet6Addr{}
    183 		if l-1 < off6 {
    184 			copy(a.IP[:], b[1:l])
    185 		} else {
    186 			copy(a.IP[:], b[l-off6:l])
    187 		}
    188 		return int(b[0]), a, nil
    189 	case b[0] == 16: // size of sockaddr_in
    190 		a := &Inet4Addr{}
    191 		copy(a.IP[:], b[off4:off4+4])
    192 		return int(b[0]), a, nil
    193 	default: // an old fashion, AF_UNSPEC or unknown means AF_INET
    194 		a := &Inet4Addr{}
    195 		if l-1 < off4 {
    196 			copy(a.IP[:], b[1:l])
    197 		} else {
    198 			copy(a.IP[:], b[l-off4:l])
    199 		}
    200 		return int(b[0]), a, nil
    201 	}
    202 }
    203 
    204 // A DefaultAddr represents an address of various operating
    205 // system-specific features.
    206 type DefaultAddr struct {
    207 	af  int
    208 	Raw []byte // raw format of address
    209 }
    210 
    211 // Family implements the Family method of Addr interface.
    212 func (a *DefaultAddr) Family() int { return a.af }
    213 
    214 func parseDefaultAddr(b []byte) (Addr, error) {
    215 	if len(b) < 2 || len(b) < int(b[0]) {
    216 		return nil, errInvalidAddr
    217 	}
    218 	a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
    219 	return a, nil
    220 }
    221 
    222 func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
    223 	var as [sysRTAX_MAX]Addr
    224 	af := int(sysAF_UNSPEC)
    225 	for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
    226 		if attrs&(1<<i) == 0 {
    227 			continue
    228 		}
    229 		if i <= sysRTAX_BRD {
    230 			switch b[1] {
    231 			case sysAF_LINK:
    232 				a, err := parseLinkAddr(b)
    233 				if err != nil {
    234 					return nil, err
    235 				}
    236 				as[i] = a
    237 				l := roundup(int(b[0]))
    238 				if len(b) < l {
    239 					return nil, errMessageTooShort
    240 				}
    241 				b = b[l:]
    242 			case sysAF_INET, sysAF_INET6:
    243 				af = int(b[1])
    244 				a, err := parseInetAddr(af, b)
    245 				if err != nil {
    246 					return nil, err
    247 				}
    248 				as[i] = a
    249 				l := roundup(int(b[0]))
    250 				if len(b) < l {
    251 					return nil, errMessageTooShort
    252 				}
    253 				b = b[l:]
    254 			default:
    255 				l, a, err := fn(af, b)
    256 				if err != nil {
    257 					return nil, err
    258 				}
    259 				as[i] = a
    260 				ll := roundup(l)
    261 				if len(b) < ll {
    262 					b = b[l:]
    263 				} else {
    264 					b = b[ll:]
    265 				}
    266 			}
    267 		} else {
    268 			a, err := parseDefaultAddr(b)
    269 			if err != nil {
    270 				return nil, err
    271 			}
    272 			as[i] = a
    273 			l := roundup(int(b[0]))
    274 			if len(b) < l {
    275 				return nil, errMessageTooShort
    276 			}
    277 			b = b[l:]
    278 		}
    279 	}
    280 	return as[:], nil
    281 }
    282