github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/x/net/route/address.go (about) 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 (a *LinkAddr) lenAndSpace() (int, int) { 28 l := 8 + len(a.Name) + len(a.Addr) 29 return l, roundup(l) 30 } 31 32 func (a *LinkAddr) marshal(b []byte) (int, error) { 33 l, ll := a.lenAndSpace() 34 if len(b) < ll { 35 return 0, errShortBuffer 36 } 37 nlen, alen := len(a.Name), len(a.Addr) 38 if nlen > 255 || alen > 255 { 39 return 0, errInvalidAddr 40 } 41 b[0] = byte(l) 42 b[1] = sysAF_LINK 43 if a.Index > 0 { 44 nativeEndian.PutUint16(b[2:4], uint16(a.Index)) 45 } 46 data := b[8:] 47 if nlen > 0 { 48 b[5] = byte(nlen) 49 copy(data[:nlen], a.Addr) 50 data = data[nlen:] 51 } 52 if alen > 0 { 53 b[6] = byte(alen) 54 copy(data[:alen], a.Name) 55 data = data[alen:] 56 } 57 return ll, nil 58 } 59 60 func parseLinkAddr(b []byte) (Addr, error) { 61 if len(b) < 8 { 62 return nil, errInvalidAddr 63 } 64 _, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:]) 65 if err != nil { 66 return nil, err 67 } 68 a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4])) 69 return a, nil 70 } 71 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 // +----------------------------+ 77 // | Type (1 octet) | 78 // +----------------------------+ 79 // | Name length (1 octet) | 80 // +----------------------------+ 81 // | Address length (1 octet) | 82 // +----------------------------+ 83 // | Selector length (1 octet) | 84 // +----------------------------+ 85 // | Data (variable) | 86 // +----------------------------+ 87 // 88 // On some platforms, all-bit-one of length field means "don't 89 // care". 90 nlen, alen, slen := int(b[1]), int(b[2]), int(b[3]) 91 if nlen == 0xff { 92 nlen = 0 93 } 94 if alen == 0xff { 95 alen = 0 96 } 97 if slen == 0xff { 98 slen = 0 99 } 100 l := 4 + nlen + alen + slen 101 if len(b) < l { 102 return 0, nil, errInvalidAddr 103 } 104 data := b[4:] 105 var name string 106 var addr []byte 107 if nlen > 0 { 108 name = string(data[:nlen]) 109 data = data[nlen:] 110 } 111 if alen > 0 { 112 addr = data[:alen] 113 data = data[alen:] 114 } 115 return l, &LinkAddr{Name: name, Addr: addr}, nil 116 } 117 118 // An Inet4Addr represents an internet address for IPv4. 119 type Inet4Addr struct { 120 IP [4]byte // IP address 121 } 122 123 // Family implements the Family method of Addr interface. 124 func (a *Inet4Addr) Family() int { return sysAF_INET } 125 126 func (a *Inet4Addr) lenAndSpace() (int, int) { 127 return sizeofSockaddrInet, roundup(sizeofSockaddrInet) 128 } 129 130 func (a *Inet4Addr) marshal(b []byte) (int, error) { 131 l, ll := a.lenAndSpace() 132 if len(b) < ll { 133 return 0, errShortBuffer 134 } 135 b[0] = byte(l) 136 b[1] = sysAF_INET 137 copy(b[4:8], a.IP[:]) 138 return ll, nil 139 } 140 141 // An Inet6Addr represents an internet address for IPv6. 142 type Inet6Addr struct { 143 IP [16]byte // IP address 144 ZoneID int // zone identifier 145 } 146 147 // Family implements the Family method of Addr interface. 148 func (a *Inet6Addr) Family() int { return sysAF_INET6 } 149 150 func (a *Inet6Addr) lenAndSpace() (int, int) { 151 return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6) 152 } 153 154 func (a *Inet6Addr) marshal(b []byte) (int, error) { 155 l, ll := a.lenAndSpace() 156 if len(b) < ll { 157 return 0, errShortBuffer 158 } 159 b[0] = byte(l) 160 b[1] = sysAF_INET6 161 copy(b[8:24], a.IP[:]) 162 if a.ZoneID > 0 { 163 nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID)) 164 } 165 return ll, nil 166 } 167 168 // parseInetAddr parses b as an internet address for IPv4 or IPv6. 169 func parseInetAddr(af int, b []byte) (Addr, error) { 170 switch af { 171 case sysAF_INET: 172 if len(b) < sizeofSockaddrInet { 173 return nil, errInvalidAddr 174 } 175 a := &Inet4Addr{} 176 copy(a.IP[:], b[4:8]) 177 return a, nil 178 case sysAF_INET6: 179 if len(b) < sizeofSockaddrInet6 { 180 return nil, errInvalidAddr 181 } 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])) 190 if id != 0 { 191 a.ZoneID = id 192 a.IP[2], a.IP[3] = 0, 0 193 } 194 } 195 return a, nil 196 default: 197 return nil, errInvalidAddr 198 } 199 } 200 201 // parseKernelInetAddr parses b as an internet address in conventional 202 // BSD kernel form. 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 // +----------------------------+ 210 // 211 // The differences between the kernel form and the NLRI 212 // encoding are: 213 // 214 // - The length field of the kernel form indicates the prefix 215 // length in bytes, not in bits 216 // 217 // - In the kernel form, zero value of the length field 218 // doesn't mean 0.0.0.0/0 or ::/0 219 // 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 223 l := int(b[0]) 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) { 228 l = roundup(l) 229 } 230 } else { 231 l = roundup(l) 232 } 233 if len(b) < l { 234 return 0, nil, errInvalidAddr 235 } 236 // Don't reorder case expressions. 237 // The case expressions for IPv6 must come first. 238 const ( 239 off4 = 4 // offset of in_addr 240 off6 = 8 // offset of in6_addr 241 ) 242 switch { 243 case b[0] == sizeofSockaddrInet6: 244 a := &Inet6Addr{} 245 copy(a.IP[:], b[off6:off6+16]) 246 return int(b[0]), a, nil 247 case af == sysAF_INET6: 248 a := &Inet6Addr{} 249 if l-1 < off6 { 250 copy(a.IP[:], b[1:l]) 251 } else { 252 copy(a.IP[:], b[l-off6:l]) 253 } 254 return int(b[0]), a, nil 255 case b[0] == sizeofSockaddrInet: 256 a := &Inet4Addr{} 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 260 a := &Inet4Addr{} 261 if l-1 < off4 { 262 copy(a.IP[:], b[1:l]) 263 } else { 264 copy(a.IP[:], b[l-off4:l]) 265 } 266 return int(b[0]), a, nil 267 } 268 } 269 270 // A DefaultAddr represents an address of various operating 271 // system-specific features. 272 type DefaultAddr struct { 273 af int 274 Raw []byte // raw format of address 275 } 276 277 // Family implements the Family method of Addr interface. 278 func (a *DefaultAddr) Family() int { return a.af } 279 280 func (a *DefaultAddr) lenAndSpace() (int, int) { 281 l := len(a.Raw) 282 return l, roundup(l) 283 } 284 285 func (a *DefaultAddr) marshal(b []byte) (int, error) { 286 l, ll := a.lenAndSpace() 287 if len(b) < ll { 288 return 0, errShortBuffer 289 } 290 if l > 255 { 291 return 0, errInvalidAddr 292 } 293 b[1] = byte(l) 294 copy(b[:l], a.Raw) 295 return ll, nil 296 } 297 298 func parseDefaultAddr(b []byte) (Addr, error) { 299 if len(b) < 2 || len(b) < int(b[0]) { 300 return nil, errInvalidAddr 301 } 302 a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]} 303 return a, nil 304 } 305 306 func addrsSpace(as []Addr) int { 307 var l int 308 for _, a := range as { 309 switch a := a.(type) { 310 case *LinkAddr: 311 _, ll := a.lenAndSpace() 312 l += ll 313 case *Inet4Addr: 314 _, ll := a.lenAndSpace() 315 l += ll 316 case *Inet6Addr: 317 _, ll := a.lenAndSpace() 318 l += ll 319 case *DefaultAddr: 320 _, ll := a.lenAndSpace() 321 l += ll 322 } 323 } 324 return l 325 } 326 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) { 330 var attrs uint 331 for i, a := range as { 332 switch a := a.(type) { 333 case *LinkAddr: 334 l, err := a.marshal(b) 335 if err != nil { 336 return 0, err 337 } 338 b = b[l:] 339 attrs |= 1 << uint(i) 340 case *Inet4Addr: 341 l, err := a.marshal(b) 342 if err != nil { 343 return 0, err 344 } 345 b = b[l:] 346 attrs |= 1 << uint(i) 347 case *Inet6Addr: 348 l, err := a.marshal(b) 349 if err != nil { 350 return 0, err 351 } 352 b = b[l:] 353 attrs |= 1 << uint(i) 354 case *DefaultAddr: 355 l, err := a.marshal(b) 356 if err != nil { 357 return 0, err 358 } 359 b = b[l:] 360 attrs |= 1 << uint(i) 361 } 362 } 363 return attrs, nil 364 } 365 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 { 371 continue 372 } 373 if i <= sysRTAX_BRD { 374 switch b[1] { 375 case sysAF_LINK: 376 a, err := parseLinkAddr(b) 377 if err != nil { 378 return nil, err 379 } 380 as[i] = a 381 l := roundup(int(b[0])) 382 if len(b) < l { 383 return nil, errMessageTooShort 384 } 385 b = b[l:] 386 case sysAF_INET, sysAF_INET6: 387 af = int(b[1]) 388 a, err := parseInetAddr(af, b) 389 if err != nil { 390 return nil, err 391 } 392 as[i] = a 393 l := roundup(int(b[0])) 394 if len(b) < l { 395 return nil, errMessageTooShort 396 } 397 b = b[l:] 398 default: 399 l, a, err := fn(af, b) 400 if err != nil { 401 return nil, err 402 } 403 as[i] = a 404 ll := roundup(l) 405 if len(b) < ll { 406 b = b[l:] 407 } else { 408 b = b[ll:] 409 } 410 } 411 } else { 412 a, err := parseDefaultAddr(b) 413 if err != nil { 414 return nil, err 415 } 416 as[i] = a 417 l := roundup(int(b[0])) 418 if len(b) < l { 419 return nil, errMessageTooShort 420 } 421 b = b[l:] 422 } 423 } 424 return as[:], nil 425 }