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