golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/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 //go:build darwin || dragonfly || freebsd || netbsd || openbsd 6 7 package route 8 9 import ( 10 "runtime" 11 "syscall" 12 ) 13 14 // An Addr represents an address associated with packet routing. 15 type Addr interface { 16 // Family returns an address family. 17 Family() int 18 } 19 20 // A LinkAddr represents a link-layer address. 21 type LinkAddr struct { 22 Index int // interface index when attached 23 Name string // interface name when attached 24 Addr []byte // link-layer address when attached 25 } 26 27 // Family implements the Family method of Addr interface. 28 func (a *LinkAddr) Family() int { return syscall.AF_LINK } 29 30 func (a *LinkAddr) lenAndSpace() (int, int) { 31 l := 8 + len(a.Name) + len(a.Addr) 32 return l, roundup(l) 33 } 34 35 func (a *LinkAddr) marshal(b []byte) (int, error) { 36 l, ll := a.lenAndSpace() 37 if len(b) < ll { 38 return 0, errShortBuffer 39 } 40 nlen, alen := len(a.Name), len(a.Addr) 41 if nlen > 255 || alen > 255 { 42 return 0, errInvalidAddr 43 } 44 b[0] = byte(l) 45 b[1] = syscall.AF_LINK 46 if a.Index > 0 { 47 nativeEndian.PutUint16(b[2:4], uint16(a.Index)) 48 } 49 data := b[8:] 50 if nlen > 0 { 51 b[5] = byte(nlen) 52 copy(data[:nlen], a.Name) 53 data = data[nlen:] 54 } 55 if alen > 0 { 56 b[6] = byte(alen) 57 copy(data[:alen], a.Addr) 58 data = data[alen:] 59 } 60 return ll, nil 61 } 62 63 func parseLinkAddr(b []byte) (Addr, error) { 64 if len(b) < 8 { 65 return nil, errInvalidAddr 66 } 67 _, a, err := parseKernelLinkAddr(syscall.AF_LINK, b[4:]) 68 if err != nil { 69 return nil, err 70 } 71 a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4])) 72 return a, nil 73 } 74 75 // parseKernelLinkAddr parses b as a link-layer address in 76 // conventional BSD kernel form. 77 func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) { 78 // The encoding looks like the following: 79 // +----------------------------+ 80 // | Type (1 octet) | 81 // +----------------------------+ 82 // | Name length (1 octet) | 83 // +----------------------------+ 84 // | Address length (1 octet) | 85 // +----------------------------+ 86 // | Selector length (1 octet) | 87 // +----------------------------+ 88 // | Data (variable) | 89 // +----------------------------+ 90 // 91 // On some platforms, all-bit-one of length field means "don't 92 // care". 93 nlen, alen, slen := int(b[1]), int(b[2]), int(b[3]) 94 if nlen == 0xff { 95 nlen = 0 96 } 97 if alen == 0xff { 98 alen = 0 99 } 100 if slen == 0xff { 101 slen = 0 102 } 103 l := 4 + nlen + alen + slen 104 if len(b) < l { 105 return 0, nil, errInvalidAddr 106 } 107 data := b[4:] 108 var name string 109 var addr []byte 110 if nlen > 0 { 111 name = string(data[:nlen]) 112 data = data[nlen:] 113 } 114 if alen > 0 { 115 addr = data[:alen] 116 data = data[alen:] 117 } 118 return l, &LinkAddr{Name: name, Addr: addr}, nil 119 } 120 121 // An Inet4Addr represents an internet address for IPv4. 122 type Inet4Addr struct { 123 IP [4]byte // IP address 124 } 125 126 // Family implements the Family method of Addr interface. 127 func (a *Inet4Addr) Family() int { return syscall.AF_INET } 128 129 func (a *Inet4Addr) lenAndSpace() (int, int) { 130 return sizeofSockaddrInet, roundup(sizeofSockaddrInet) 131 } 132 133 func (a *Inet4Addr) marshal(b []byte) (int, error) { 134 l, ll := a.lenAndSpace() 135 if len(b) < ll { 136 return 0, errShortBuffer 137 } 138 b[0] = byte(l) 139 b[1] = syscall.AF_INET 140 copy(b[4:8], a.IP[:]) 141 return ll, nil 142 } 143 144 // An Inet6Addr represents an internet address for IPv6. 145 type Inet6Addr struct { 146 IP [16]byte // IP address 147 ZoneID int // zone identifier 148 } 149 150 // Family implements the Family method of Addr interface. 151 func (a *Inet6Addr) Family() int { return syscall.AF_INET6 } 152 153 func (a *Inet6Addr) lenAndSpace() (int, int) { 154 return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6) 155 } 156 157 func (a *Inet6Addr) marshal(b []byte) (int, error) { 158 l, ll := a.lenAndSpace() 159 if len(b) < ll { 160 return 0, errShortBuffer 161 } 162 b[0] = byte(l) 163 b[1] = syscall.AF_INET6 164 copy(b[8:24], a.IP[:]) 165 if a.ZoneID > 0 { 166 nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID)) 167 } 168 return ll, nil 169 } 170 171 // parseInetAddr parses b as an internet address for IPv4 or IPv6. 172 func parseInetAddr(af int, b []byte) (Addr, error) { 173 switch af { 174 case syscall.AF_INET: 175 if len(b) < sizeofSockaddrInet { 176 return nil, errInvalidAddr 177 } 178 a := &Inet4Addr{} 179 copy(a.IP[:], b[4:8]) 180 return a, nil 181 case syscall.AF_INET6: 182 if len(b) < sizeofSockaddrInet6 { 183 return nil, errInvalidAddr 184 } 185 a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))} 186 copy(a.IP[:], b[8:24]) 187 if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) { 188 // KAME based IPv6 protocol stack usually 189 // embeds the interface index in the 190 // interface-local or link-local address as 191 // the kernel-internal form. 192 id := int(bigEndian.Uint16(a.IP[2:4])) 193 if id != 0 { 194 a.ZoneID = id 195 a.IP[2], a.IP[3] = 0, 0 196 } 197 } 198 return a, nil 199 default: 200 return nil, errInvalidAddr 201 } 202 } 203 204 // parseKernelInetAddr parses b as an internet address in conventional 205 // BSD kernel form. 206 func parseKernelInetAddr(af int, b []byte) (int, Addr, error) { 207 // The encoding looks similar to the NLRI encoding. 208 // +----------------------------+ 209 // | Length (1 octet) | 210 // +----------------------------+ 211 // | Address prefix (variable) | 212 // +----------------------------+ 213 // 214 // The differences between the kernel form and the NLRI 215 // encoding are: 216 // 217 // - The length field of the kernel form indicates the prefix 218 // length in bytes, not in bits 219 // 220 // - In the kernel form, zero value of the length field 221 // doesn't mean 0.0.0.0/0 or ::/0 222 // 223 // - The kernel form appends leading bytes to the prefix field 224 // to make the <length, prefix> tuple to be conformed with 225 // the routing message boundary 226 l := int(b[0]) 227 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { 228 // On Darwin, an address in the kernel form is also 229 // used as a message filler. 230 if l == 0 || len(b) > roundup(l) { 231 l = roundup(l) 232 } 233 } else { 234 l = roundup(l) 235 } 236 if len(b) < l { 237 return 0, nil, errInvalidAddr 238 } 239 // Don't reorder case expressions. 240 // The case expressions for IPv6 must come first. 241 const ( 242 off4 = 4 // offset of in_addr 243 off6 = 8 // offset of in6_addr 244 ) 245 switch { 246 case b[0] == sizeofSockaddrInet6: 247 a := &Inet6Addr{} 248 copy(a.IP[:], b[off6:off6+16]) 249 return int(b[0]), a, nil 250 case af == syscall.AF_INET6: 251 a := &Inet6Addr{} 252 if l-1 < off6 { 253 copy(a.IP[:], b[1:l]) 254 } else { 255 copy(a.IP[:], b[l-off6:l]) 256 } 257 return int(b[0]), a, nil 258 case b[0] == sizeofSockaddrInet: 259 a := &Inet4Addr{} 260 copy(a.IP[:], b[off4:off4+4]) 261 return int(b[0]), a, nil 262 default: // an old fashion, AF_UNSPEC or unknown means AF_INET 263 a := &Inet4Addr{} 264 if l-1 < off4 { 265 copy(a.IP[:], b[1:l]) 266 } else { 267 copy(a.IP[:], b[l-off4:l]) 268 } 269 return int(b[0]), a, nil 270 } 271 } 272 273 // A DefaultAddr represents an address of various operating 274 // system-specific features. 275 type DefaultAddr struct { 276 af int 277 Raw []byte // raw format of address 278 } 279 280 // Family implements the Family method of Addr interface. 281 func (a *DefaultAddr) Family() int { return a.af } 282 283 func (a *DefaultAddr) lenAndSpace() (int, int) { 284 l := len(a.Raw) 285 return l, roundup(l) 286 } 287 288 func (a *DefaultAddr) marshal(b []byte) (int, error) { 289 l, ll := a.lenAndSpace() 290 if len(b) < ll { 291 return 0, errShortBuffer 292 } 293 if l > 255 { 294 return 0, errInvalidAddr 295 } 296 b[1] = byte(l) 297 copy(b[:l], a.Raw) 298 return ll, nil 299 } 300 301 func parseDefaultAddr(b []byte) (Addr, error) { 302 if len(b) < 2 || len(b) < int(b[0]) { 303 return nil, errInvalidAddr 304 } 305 a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]} 306 return a, nil 307 } 308 309 func addrsSpace(as []Addr) int { 310 var l int 311 for _, a := range as { 312 switch a := a.(type) { 313 case *LinkAddr: 314 _, ll := a.lenAndSpace() 315 l += ll 316 case *Inet4Addr: 317 _, ll := a.lenAndSpace() 318 l += ll 319 case *Inet6Addr: 320 _, ll := a.lenAndSpace() 321 l += ll 322 case *DefaultAddr: 323 _, ll := a.lenAndSpace() 324 l += ll 325 } 326 } 327 return l 328 } 329 330 // marshalAddrs marshals as and returns a bitmap indicating which 331 // address is stored in b. 332 func marshalAddrs(b []byte, as []Addr) (uint, error) { 333 var attrs uint 334 for i, a := range as { 335 switch a := a.(type) { 336 case *LinkAddr: 337 l, err := a.marshal(b) 338 if err != nil { 339 return 0, err 340 } 341 b = b[l:] 342 attrs |= 1 << uint(i) 343 case *Inet4Addr: 344 l, err := a.marshal(b) 345 if err != nil { 346 return 0, err 347 } 348 b = b[l:] 349 attrs |= 1 << uint(i) 350 case *Inet6Addr: 351 l, err := a.marshal(b) 352 if err != nil { 353 return 0, err 354 } 355 b = b[l:] 356 attrs |= 1 << uint(i) 357 case *DefaultAddr: 358 l, err := a.marshal(b) 359 if err != nil { 360 return 0, err 361 } 362 b = b[l:] 363 attrs |= 1 << uint(i) 364 } 365 } 366 return attrs, nil 367 } 368 369 func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) { 370 var as [syscall.RTAX_MAX]Addr 371 af := int(syscall.AF_UNSPEC) 372 for i := uint(0); i < syscall.RTAX_MAX && len(b) >= roundup(0); i++ { 373 if attrs&(1<<i) == 0 { 374 continue 375 } 376 if i <= syscall.RTAX_BRD { 377 switch b[1] { 378 case syscall.AF_LINK: 379 a, err := parseLinkAddr(b) 380 if err != nil { 381 return nil, err 382 } 383 as[i] = a 384 l := roundup(int(b[0])) 385 if len(b) < l { 386 return nil, errMessageTooShort 387 } 388 b = b[l:] 389 case syscall.AF_INET, syscall.AF_INET6: 390 af = int(b[1]) 391 a, err := parseInetAddr(af, b) 392 if err != nil { 393 return nil, err 394 } 395 as[i] = a 396 l := roundup(int(b[0])) 397 if len(b) < l { 398 return nil, errMessageTooShort 399 } 400 b = b[l:] 401 default: 402 l, a, err := fn(af, b) 403 if err != nil { 404 return nil, err 405 } 406 as[i] = a 407 ll := roundup(l) 408 if len(b) < ll { 409 b = b[l:] 410 } else { 411 b = b[ll:] 412 } 413 } 414 } else { 415 a, err := parseDefaultAddr(b) 416 if err != nil { 417 return nil, err 418 } 419 as[i] = a 420 l := roundup(int(b[0])) 421 if len(b) < l { 422 return nil, errMessageTooShort 423 } 424 b = b[l:] 425 } 426 } 427 // The only remaining bytes in b should be alignment. 428 // However, under some circumstances DragonFly BSD appears to put 429 // more addresses in the message than are indicated in the address 430 // bitmask, so don't check for this. 431 return as[:], nil 432 }