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