inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/tcpip/header/ipv4.go (about) 1 // Copyright 2021 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package header 16 17 import ( 18 "encoding/binary" 19 "fmt" 20 "time" 21 22 "inet.af/netstack/tcpip" 23 ) 24 25 // RFC 971 defines the fields of the IPv4 header on page 11 using the following 26 // diagram: ("Figure 4") 27 // 0 1 2 3 28 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 29 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 // |Version| IHL |Type of Service| Total Length | 31 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 // | Identification |Flags| Fragment Offset | 33 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 34 // | Time to Live | Protocol | Header Checksum | 35 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 36 // | Source Address | 37 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 38 // | Destination Address | 39 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 40 // | Options | Padding | 41 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 42 const ( 43 versIHL = 0 44 tos = 1 45 // IPv4TotalLenOffset is the offset of the total length field in the 46 // IPv4 header. 47 IPv4TotalLenOffset = 2 48 id = 4 49 flagsFO = 6 50 ttl = 8 51 protocol = 9 52 checksum = 10 53 srcAddr = 12 54 dstAddr = 16 55 options = 20 56 ) 57 58 // IPv4Fields contains the fields of an IPv4 packet. It is used to describe the 59 // fields of a packet that needs to be encoded. The IHL field is not here as 60 // it is totally defined by the size of the options. 61 type IPv4Fields struct { 62 // TOS is the "type of service" field of an IPv4 packet. 63 TOS uint8 64 65 // TotalLength is the "total length" field of an IPv4 packet. 66 TotalLength uint16 67 68 // ID is the "identification" field of an IPv4 packet. 69 ID uint16 70 71 // Flags is the "flags" field of an IPv4 packet. 72 Flags uint8 73 74 // FragmentOffset is the "fragment offset" field of an IPv4 packet. 75 FragmentOffset uint16 76 77 // TTL is the "time to live" field of an IPv4 packet. 78 TTL uint8 79 80 // Protocol is the "protocol" field of an IPv4 packet. 81 Protocol uint8 82 83 // Checksum is the "checksum" field of an IPv4 packet. 84 Checksum uint16 85 86 // SrcAddr is the "source ip address" of an IPv4 packet. 87 SrcAddr tcpip.Address 88 89 // DstAddr is the "destination ip address" of an IPv4 packet. 90 DstAddr tcpip.Address 91 92 // Options must be 40 bytes or less as they must fit along with the 93 // rest of the IPv4 header into the maximum size describable in the 94 // IHL field. RFC 791 section 3.1 says: 95 // IHL: 4 bits 96 // 97 // Internet Header Length is the length of the internet header in 32 98 // bit words, and thus points to the beginning of the data. Note that 99 // the minimum value for a correct header is 5. 100 // 101 // That leaves ten 32 bit (4 byte) fields for options. An attempt to encode 102 // more will fail. 103 Options IPv4OptionsSerializer 104 } 105 106 // IPv4 is an IPv4 header. 107 // Most of the methods of IPv4 access to the underlying slice without 108 // checking the boundaries and could panic because of 'index out of range'. 109 // Always call IsValid() to validate an instance of IPv4 before using other 110 // methods. 111 type IPv4 []byte 112 113 const ( 114 // IPv4MinimumSize is the minimum size of a valid IPv4 packet; 115 // i.e. a packet header with no options. 116 IPv4MinimumSize = 20 117 118 // IPv4MaximumHeaderSize is the maximum size of an IPv4 header. Given 119 // that there are only 4 bits (max 0xF (15)) to represent the header length 120 // in 32-bit (4 byte) units, the header cannot exceed 15*4 = 60 bytes. 121 IPv4MaximumHeaderSize = 60 122 123 // IPv4MaximumOptionsSize is the largest size the IPv4 options can be. 124 IPv4MaximumOptionsSize = IPv4MaximumHeaderSize - IPv4MinimumSize 125 126 // IPv4MaximumPayloadSize is the maximum size of a valid IPv4 payload. 127 // 128 // Linux limits this to 65,515 octets (the max IP datagram size - the IPv4 129 // header size). But RFC 791 section 3.2 discusses the design of the IPv4 130 // fragment "allows 2**13 = 8192 fragments of 8 octets each for a total of 131 // 65,536 octets. Note that this is consistent with the datagram total 132 // length field (of course, the header is counted in the total length and not 133 // in the fragments)." 134 IPv4MaximumPayloadSize = 65536 135 136 // MinIPFragmentPayloadSize is the minimum number of payload bytes that 137 // the first fragment must carry when an IPv4 packet is fragmented. 138 MinIPFragmentPayloadSize = 8 139 140 // IPv4AddressSize is the size, in bytes, of an IPv4 address. 141 IPv4AddressSize = 4 142 143 // IPv4ProtocolNumber is IPv4's network protocol number. 144 IPv4ProtocolNumber tcpip.NetworkProtocolNumber = 0x0800 145 146 // IPv4Version is the version of the IPv4 protocol. 147 IPv4Version = 4 148 149 // IPv4AllSystems is the all systems IPv4 multicast address as per 150 // IANA's IPv4 Multicast Address Space Registry. See 151 // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml. 152 IPv4AllSystems tcpip.Address = "\xe0\x00\x00\x01" 153 154 // IPv4Broadcast is the broadcast address of the IPv4 procotol. 155 IPv4Broadcast tcpip.Address = "\xff\xff\xff\xff" 156 157 // IPv4Any is the non-routable IPv4 "any" meta address. 158 IPv4Any tcpip.Address = "\x00\x00\x00\x00" 159 160 // IPv4AllRoutersGroup is a multicast address for all routers. 161 IPv4AllRoutersGroup tcpip.Address = "\xe0\x00\x00\x02" 162 163 // IPv4MinimumProcessableDatagramSize is the minimum size of an IP 164 // packet that every IPv4 capable host must be able to 165 // process/reassemble. 166 IPv4MinimumProcessableDatagramSize = 576 167 168 // IPv4MinimumMTU is the minimum MTU required by IPv4, per RFC 791, 169 // section 3.2: 170 // Every internet module must be able to forward a datagram of 68 octets 171 // without further fragmentation. This is because an internet header may be 172 // up to 60 octets, and the minimum fragment is 8 octets. 173 IPv4MinimumMTU = 68 174 ) 175 176 // Flags that may be set in an IPv4 packet. 177 const ( 178 IPv4FlagMoreFragments = 1 << iota 179 IPv4FlagDontFragment 180 ) 181 182 // ipv4LinkLocalUnicastSubnet is the IPv4 link local unicast subnet as defined 183 // by RFC 3927 section 1. 184 var ipv4LinkLocalUnicastSubnet = func() tcpip.Subnet { 185 subnet, err := tcpip.NewSubnet("\xa9\xfe\x00\x00", "\xff\xff\x00\x00") 186 if err != nil { 187 panic(err) 188 } 189 return subnet 190 }() 191 192 // ipv4LinkLocalMulticastSubnet is the IPv4 link local multicast subnet as 193 // defined by RFC 5771 section 4. 194 var ipv4LinkLocalMulticastSubnet = func() tcpip.Subnet { 195 subnet, err := tcpip.NewSubnet("\xe0\x00\x00\x00", "\xff\xff\xff\x00") 196 if err != nil { 197 panic(err) 198 } 199 return subnet 200 }() 201 202 // IPv4EmptySubnet is the empty IPv4 subnet. 203 var IPv4EmptySubnet = func() tcpip.Subnet { 204 subnet, err := tcpip.NewSubnet(IPv4Any, tcpip.AddressMask(IPv4Any)) 205 if err != nil { 206 panic(err) 207 } 208 return subnet 209 }() 210 211 // IPv4LoopbackSubnet is the loopback subnet for IPv4. 212 var IPv4LoopbackSubnet = func() tcpip.Subnet { 213 subnet, err := tcpip.NewSubnet(tcpip.Address("\x7f\x00\x00\x00"), tcpip.AddressMask("\xff\x00\x00\x00")) 214 if err != nil { 215 panic(err) 216 } 217 return subnet 218 }() 219 220 // IPVersion returns the version of IP used in the given packet. It returns -1 221 // if the packet is not large enough to contain the version field. 222 func IPVersion(b []byte) int { 223 // Length must be at least offset+length of version field. 224 if len(b) < versIHL+1 { 225 return -1 226 } 227 return int(b[versIHL] >> ipVersionShift) 228 } 229 230 // RFC 791 page 11 shows the header length (IHL) is in the lower 4 bits 231 // of the first byte, and is counted in multiples of 4 bytes. 232 // 233 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 234 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 235 // |Version| IHL |Type of Service| Total Length | 236 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 237 // (...) 238 // Version: 4 bits 239 // The Version field indicates the format of the internet header. This 240 // document describes version 4. 241 // 242 // IHL: 4 bits 243 // Internet Header Length is the length of the internet header in 32 244 // bit words, and thus points to the beginning of the data. Note that 245 // the minimum value for a correct header is 5. 246 const ( 247 ipVersionShift = 4 248 ipIHLMask = 0x0f 249 IPv4IHLStride = 4 250 ) 251 252 // HeaderLength returns the value of the "header length" field of the IPv4 253 // header. The length returned is in bytes. 254 func (b IPv4) HeaderLength() uint8 { 255 return (b[versIHL] & ipIHLMask) * IPv4IHLStride 256 } 257 258 // SetHeaderLength sets the value of the "Internet Header Length" field. 259 func (b IPv4) SetHeaderLength(hdrLen uint8) { 260 if hdrLen > IPv4MaximumHeaderSize { 261 panic(fmt.Sprintf("got IPv4 Header size = %d, want <= %d", hdrLen, IPv4MaximumHeaderSize)) 262 } 263 b[versIHL] = (IPv4Version << ipVersionShift) | ((hdrLen / IPv4IHLStride) & ipIHLMask) 264 } 265 266 // ID returns the value of the identifier field of the IPv4 header. 267 func (b IPv4) ID() uint16 { 268 return binary.BigEndian.Uint16(b[id:]) 269 } 270 271 // Protocol returns the value of the protocol field of the IPv4 header. 272 func (b IPv4) Protocol() uint8 { 273 return b[protocol] 274 } 275 276 // Flags returns the "flags" field of the IPv4 header. 277 func (b IPv4) Flags() uint8 { 278 return uint8(binary.BigEndian.Uint16(b[flagsFO:]) >> 13) 279 } 280 281 // More returns whether the more fragments flag is set. 282 func (b IPv4) More() bool { 283 return b.Flags()&IPv4FlagMoreFragments != 0 284 } 285 286 // TTL returns the "TTL" field of the IPv4 header. 287 func (b IPv4) TTL() uint8 { 288 return b[ttl] 289 } 290 291 // FragmentOffset returns the "fragment offset" field of the IPv4 header. 292 func (b IPv4) FragmentOffset() uint16 { 293 return binary.BigEndian.Uint16(b[flagsFO:]) << 3 294 } 295 296 // TotalLength returns the "total length" field of the IPv4 header. 297 func (b IPv4) TotalLength() uint16 { 298 return binary.BigEndian.Uint16(b[IPv4TotalLenOffset:]) 299 } 300 301 // Checksum returns the checksum field of the IPv4 header. 302 func (b IPv4) Checksum() uint16 { 303 return binary.BigEndian.Uint16(b[checksum:]) 304 } 305 306 // SourceAddress returns the "source address" field of the IPv4 header. 307 func (b IPv4) SourceAddress() tcpip.Address { 308 return tcpip.Address(b[srcAddr : srcAddr+IPv4AddressSize]) 309 } 310 311 // DestinationAddress returns the "destination address" field of the IPv4 312 // header. 313 func (b IPv4) DestinationAddress() tcpip.Address { 314 return tcpip.Address(b[dstAddr : dstAddr+IPv4AddressSize]) 315 } 316 317 // SetSourceAddressWithChecksumUpdate implements ChecksummableNetwork. 318 func (b IPv4) SetSourceAddressWithChecksumUpdate(new tcpip.Address) { 319 b.SetChecksum(^checksumUpdate2ByteAlignedAddress(^b.Checksum(), b.SourceAddress(), new)) 320 b.SetSourceAddress(new) 321 } 322 323 // SetDestinationAddressWithChecksumUpdate implements ChecksummableNetwork. 324 func (b IPv4) SetDestinationAddressWithChecksumUpdate(new tcpip.Address) { 325 b.SetChecksum(^checksumUpdate2ByteAlignedAddress(^b.Checksum(), b.DestinationAddress(), new)) 326 b.SetDestinationAddress(new) 327 } 328 329 // padIPv4OptionsLength returns the total length for IPv4 options of length l 330 // after applying padding according to RFC 791: 331 // The internet header padding is used to ensure that the internet 332 // header ends on a 32 bit boundary. 333 func padIPv4OptionsLength(length uint8) uint8 { 334 return (length + IPv4IHLStride - 1) & ^uint8(IPv4IHLStride-1) 335 } 336 337 // IPv4Options is a buffer that holds all the raw IP options. 338 type IPv4Options []byte 339 340 // Options returns a buffer holding the options. 341 func (b IPv4) Options() IPv4Options { 342 hdrLen := b.HeaderLength() 343 return IPv4Options(b[options:hdrLen:hdrLen]) 344 } 345 346 // TransportProtocol implements Network.TransportProtocol. 347 func (b IPv4) TransportProtocol() tcpip.TransportProtocolNumber { 348 return tcpip.TransportProtocolNumber(b.Protocol()) 349 } 350 351 // Payload implements Network.Payload. 352 func (b IPv4) Payload() []byte { 353 return b[b.HeaderLength():][:b.PayloadLength()] 354 } 355 356 // PayloadLength returns the length of the payload portion of the IPv4 packet. 357 func (b IPv4) PayloadLength() uint16 { 358 return b.TotalLength() - uint16(b.HeaderLength()) 359 } 360 361 // TOS returns the "type of service" field of the IPv4 header. 362 func (b IPv4) TOS() (uint8, uint32) { 363 return b[tos], 0 364 } 365 366 // SetTOS sets the "type of service" field of the IPv4 header. 367 func (b IPv4) SetTOS(v uint8, _ uint32) { 368 b[tos] = v 369 } 370 371 // SetTTL sets the "Time to Live" field of the IPv4 header. 372 func (b IPv4) SetTTL(v byte) { 373 b[ttl] = v 374 } 375 376 // SetTotalLength sets the "total length" field of the IPv4 header. 377 func (b IPv4) SetTotalLength(totalLength uint16) { 378 binary.BigEndian.PutUint16(b[IPv4TotalLenOffset:], totalLength) 379 } 380 381 // SetChecksum sets the checksum field of the IPv4 header. 382 func (b IPv4) SetChecksum(v uint16) { 383 binary.BigEndian.PutUint16(b[checksum:], v) 384 } 385 386 // SetFlagsFragmentOffset sets the "flags" and "fragment offset" fields of the 387 // IPv4 header. 388 func (b IPv4) SetFlagsFragmentOffset(flags uint8, offset uint16) { 389 v := (uint16(flags) << 13) | (offset >> 3) 390 binary.BigEndian.PutUint16(b[flagsFO:], v) 391 } 392 393 // SetID sets the identification field. 394 func (b IPv4) SetID(v uint16) { 395 binary.BigEndian.PutUint16(b[id:], v) 396 } 397 398 // SetSourceAddress sets the "source address" field of the IPv4 header. 399 func (b IPv4) SetSourceAddress(addr tcpip.Address) { 400 copy(b[srcAddr:srcAddr+IPv4AddressSize], addr) 401 } 402 403 // SetDestinationAddress sets the "destination address" field of the IPv4 404 // header. 405 func (b IPv4) SetDestinationAddress(addr tcpip.Address) { 406 copy(b[dstAddr:dstAddr+IPv4AddressSize], addr) 407 } 408 409 // CalculateChecksum calculates the checksum of the IPv4 header. 410 func (b IPv4) CalculateChecksum() uint16 { 411 return Checksum(b[:b.HeaderLength()], 0) 412 } 413 414 // Encode encodes all the fields of the IPv4 header. 415 func (b IPv4) Encode(i *IPv4Fields) { 416 // The size of the options defines the size of the whole header and thus the 417 // IHL field. Options are rare and this is a heavily used function so it is 418 // worth a bit of optimisation here to keep the serializer out of the fast 419 // path. 420 hdrLen := uint8(IPv4MinimumSize) 421 if len(i.Options) != 0 { 422 hdrLen += i.Options.Serialize(b[options:]) 423 } 424 if hdrLen > IPv4MaximumHeaderSize { 425 panic(fmt.Sprintf("%d is larger than maximum IPv4 header size of %d", hdrLen, IPv4MaximumHeaderSize)) 426 } 427 b.SetHeaderLength(hdrLen) 428 b[tos] = i.TOS 429 b.SetTotalLength(i.TotalLength) 430 binary.BigEndian.PutUint16(b[id:], i.ID) 431 b.SetFlagsFragmentOffset(i.Flags, i.FragmentOffset) 432 b[ttl] = i.TTL 433 b[protocol] = i.Protocol 434 b.SetChecksum(i.Checksum) 435 copy(b[srcAddr:srcAddr+IPv4AddressSize], i.SrcAddr) 436 copy(b[dstAddr:dstAddr+IPv4AddressSize], i.DstAddr) 437 } 438 439 // EncodePartial updates the total length and checksum fields of IPv4 header, 440 // taking in the partial checksum, which is the checksum of the header without 441 // the total length and checksum fields. It is useful in cases when similar 442 // packets are produced. 443 func (b IPv4) EncodePartial(partialChecksum, totalLength uint16) { 444 b.SetTotalLength(totalLength) 445 checksum := Checksum(b[IPv4TotalLenOffset:IPv4TotalLenOffset+2], partialChecksum) 446 b.SetChecksum(^checksum) 447 } 448 449 // IsValid performs basic validation on the packet. 450 func (b IPv4) IsValid(pktSize int) bool { 451 if len(b) < IPv4MinimumSize { 452 return false 453 } 454 455 hlen := int(b.HeaderLength()) 456 tlen := int(b.TotalLength()) 457 if hlen < IPv4MinimumSize || hlen > tlen || tlen > pktSize { 458 return false 459 } 460 461 if IPVersion(b) != IPv4Version { 462 return false 463 } 464 465 return true 466 } 467 468 // IsV4LinkLocalUnicastAddress determines if the provided address is an IPv4 469 // link-local unicast address. 470 func IsV4LinkLocalUnicastAddress(addr tcpip.Address) bool { 471 return ipv4LinkLocalUnicastSubnet.Contains(addr) 472 } 473 474 // IsV4LinkLocalMulticastAddress determines if the provided address is an IPv4 475 // link-local multicast address. 476 func IsV4LinkLocalMulticastAddress(addr tcpip.Address) bool { 477 return ipv4LinkLocalMulticastSubnet.Contains(addr) 478 } 479 480 // IsChecksumValid returns true iff the IPv4 header's checksum is valid. 481 func (b IPv4) IsChecksumValid() bool { 482 // There has been some confusion regarding verifying checksums. We need 483 // just look for negative 0 (0xffff) as the checksum, as it's not possible to 484 // get positive 0 (0) for the checksum. Some bad implementations could get it 485 // when doing entry replacement in the early days of the Internet, 486 // however the lore that one needs to check for both persists. 487 // 488 // RFC 1624 section 1 describes the source of this confusion as: 489 // [the partial recalculation method described in RFC 1071] computes a 490 // result for certain cases that differs from the one obtained from 491 // scratch (one's complement of one's complement sum of the original 492 // fields). 493 // 494 // However RFC 1624 section 5 clarifies that if using the verification method 495 // "recommended by RFC 1071, it does not matter if an intermediate system 496 // generated a -0 instead of +0". 497 // 498 // RFC1071 page 1 specifies the verification method as: 499 // (3) To check a checksum, the 1's complement sum is computed over the 500 // same set of octets, including the checksum field. If the result 501 // is all 1 bits (-0 in 1's complement arithmetic), the check 502 // succeeds. 503 return b.CalculateChecksum() == 0xffff 504 } 505 506 // IsV4MulticastAddress determines if the provided address is an IPv4 multicast 507 // address (range 224.0.0.0 to 239.255.255.255). The four most significant bits 508 // will be 1110 = 0xe0. 509 func IsV4MulticastAddress(addr tcpip.Address) bool { 510 if len(addr) != IPv4AddressSize { 511 return false 512 } 513 return (addr[0] & 0xf0) == 0xe0 514 } 515 516 // IsV4LoopbackAddress determines if the provided address is an IPv4 loopback 517 // address (belongs to 127.0.0.0/8 subnet). See RFC 1122 section 3.2.1.3. 518 func IsV4LoopbackAddress(addr tcpip.Address) bool { 519 if len(addr) != IPv4AddressSize { 520 return false 521 } 522 return addr[0] == 0x7f 523 } 524 525 // ========================= Options ========================== 526 527 // An IPv4OptionType can hold the valuse for the Type in an IPv4 option. 528 type IPv4OptionType byte 529 530 // These constants are needed to identify individual options in the option list. 531 // While RFC 791 (page 31) says "Every internet module must be able to act on 532 // every option." This has not generally been adhered to and some options have 533 // very low rates of support. We do not support options other than those shown 534 // below. 535 536 const ( 537 // IPv4OptionListEndType is the option type for the End Of Option List 538 // option. Anything following is ignored. 539 IPv4OptionListEndType IPv4OptionType = 0 540 541 // IPv4OptionNOPType is the No-Operation option. May appear between other 542 // options and may appear multiple times. 543 IPv4OptionNOPType IPv4OptionType = 1 544 545 // IPv4OptionRouterAlertType is the option type for the Router Alert option, 546 // defined in RFC 2113 Section 2.1. 547 IPv4OptionRouterAlertType IPv4OptionType = 20 | 0x80 548 549 // IPv4OptionRecordRouteType is used by each router on the path of the packet 550 // to record its path. It is carried over to an Echo Reply. 551 IPv4OptionRecordRouteType IPv4OptionType = 7 552 553 // IPv4OptionTimestampType is the option type for the Timestamp option. 554 IPv4OptionTimestampType IPv4OptionType = 68 555 556 // ipv4OptionTypeOffset is the offset in an option of its type field. 557 ipv4OptionTypeOffset = 0 558 559 // IPv4OptionLengthOffset is the offset in an option of its length field. 560 IPv4OptionLengthOffset = 1 561 ) 562 563 // IPv4OptParameterProblem indicates that a Parameter Problem message 564 // should be generated, and gives the offset in the current entity 565 // that should be used in that packet. 566 type IPv4OptParameterProblem struct { 567 Pointer uint8 568 NeedICMP bool 569 } 570 571 // IPv4Option is an interface representing various option types. 572 type IPv4Option interface { 573 // Type returns the type identifier of the option. 574 Type() IPv4OptionType 575 576 // Size returns the size of the option in bytes. 577 Size() uint8 578 579 // Contents returns a slice holding the contents of the option. 580 Contents() []byte 581 } 582 583 var _ IPv4Option = (*IPv4OptionGeneric)(nil) 584 585 // IPv4OptionGeneric is an IPv4 Option of unknown type. 586 type IPv4OptionGeneric []byte 587 588 // Type implements IPv4Option. 589 func (o *IPv4OptionGeneric) Type() IPv4OptionType { 590 return IPv4OptionType((*o)[ipv4OptionTypeOffset]) 591 } 592 593 // Size implements IPv4Option. 594 func (o *IPv4OptionGeneric) Size() uint8 { return uint8(len(*o)) } 595 596 // Contents implements IPv4Option. 597 func (o *IPv4OptionGeneric) Contents() []byte { return *o } 598 599 // IPv4OptionIterator is an iterator pointing to a specific IP option 600 // at any point of time. It also holds information as to a new options buffer 601 // that we are building up to hand back to the caller. 602 // TODO(https://gvisor.dev/issues/5513): Add unit tests for IPv4OptionIterator. 603 type IPv4OptionIterator struct { 604 options IPv4Options 605 // ErrCursor is where we are while parsing options. It is exported as any 606 // resulting ICMP packet is supposed to have a pointer to the byte within 607 // the IP packet where the error was detected. 608 ErrCursor uint8 609 nextErrCursor uint8 610 newOptions [IPv4MaximumOptionsSize]byte 611 writePoint int 612 } 613 614 // MakeIterator sets up and returns an iterator of options. It also sets up the 615 // building of a new option set. 616 func (o IPv4Options) MakeIterator() IPv4OptionIterator { 617 return IPv4OptionIterator{ 618 options: o, 619 nextErrCursor: IPv4MinimumSize, 620 } 621 } 622 623 // InitReplacement copies the option into the new option buffer. 624 func (i *IPv4OptionIterator) InitReplacement(option IPv4Option) IPv4Options { 625 replacementOption := i.RemainingBuffer()[:option.Size()] 626 if copied := copy(replacementOption, option.Contents()); copied != len(replacementOption) { 627 panic(fmt.Sprintf("copied %d bytes in the replacement option buffer, expected %d bytes", copied, len(replacementOption))) 628 } 629 return replacementOption 630 } 631 632 // RemainingBuffer returns the remaining (unused) part of the new option buffer, 633 // into which a new option may be written. 634 func (i *IPv4OptionIterator) RemainingBuffer() IPv4Options { 635 return i.newOptions[i.writePoint:] 636 } 637 638 // ConsumeBuffer marks a portion of the new buffer as used. 639 func (i *IPv4OptionIterator) ConsumeBuffer(size int) { 640 i.writePoint += size 641 } 642 643 // PushNOPOrEnd puts one of the single byte options onto the new options. 644 // Only values 0 or 1 (ListEnd or NOP) are valid input. 645 func (i *IPv4OptionIterator) PushNOPOrEnd(val IPv4OptionType) { 646 if val > IPv4OptionNOPType { 647 panic(fmt.Sprintf("invalid option type %d pushed onto option build buffer", val)) 648 } 649 i.newOptions[i.writePoint] = byte(val) 650 i.writePoint++ 651 } 652 653 // Finalize returns the completed replacement options buffer padded 654 // as needed. 655 func (i *IPv4OptionIterator) Finalize() IPv4Options { 656 // RFC 791 page 31 says: 657 // The options might not end on a 32-bit boundary. The internet header 658 // must be filled out with octets of zeros. The first of these would 659 // be interpreted as the end-of-options option, and the remainder as 660 // internet header padding. 661 // Since the buffer is already zero filled we just need to step the write 662 // pointer up to the next multiple of 4. 663 options := IPv4Options(i.newOptions[:(i.writePoint+0x3) & ^0x3]) 664 // Poison the write pointer. 665 i.writePoint = len(i.newOptions) 666 return options 667 } 668 669 // Next returns the next IP option in the buffer/list of IP options. 670 // It returns 671 // - A slice of bytes holding the next option or nil if there is error. 672 // - A boolean which is true if parsing of all the options is complete. 673 // Undefined in the case of error. 674 // - An error indication which is non-nil if an error condition was found. 675 func (i *IPv4OptionIterator) Next() (IPv4Option, bool, *IPv4OptParameterProblem) { 676 // The opts slice gets shorter as we process the options. When we have no 677 // bytes left we are done. 678 if len(i.options) == 0 { 679 return nil, true, nil 680 } 681 682 i.ErrCursor = i.nextErrCursor 683 684 optType := IPv4OptionType(i.options[ipv4OptionTypeOffset]) 685 686 if optType == IPv4OptionNOPType || optType == IPv4OptionListEndType { 687 optionBody := i.options[:1] 688 i.options = i.options[1:] 689 i.nextErrCursor = i.ErrCursor + 1 690 retval := IPv4OptionGeneric(optionBody) 691 return &retval, false, nil 692 } 693 694 // There are no more single byte options defined. All the rest have a length 695 // field so we need to sanity check it. 696 if len(i.options) == 1 { 697 return nil, false, &IPv4OptParameterProblem{ 698 Pointer: i.ErrCursor, 699 NeedICMP: true, 700 } 701 } 702 703 optLen := i.options[IPv4OptionLengthOffset] 704 705 if optLen <= IPv4OptionLengthOffset || optLen > uint8(len(i.options)) { 706 // The actual error is in the length (2nd byte of the option) but we 707 // return the start of the option for compatibility with Linux. 708 709 return nil, false, &IPv4OptParameterProblem{ 710 Pointer: i.ErrCursor, 711 NeedICMP: true, 712 } 713 } 714 715 optionBody := i.options[:optLen] 716 i.nextErrCursor = i.ErrCursor + optLen 717 i.options = i.options[optLen:] 718 719 // Check the length of some option types that we know. 720 switch optType { 721 case IPv4OptionTimestampType: 722 if optLen < IPv4OptionTimestampHdrLength { 723 i.ErrCursor++ 724 return nil, false, &IPv4OptParameterProblem{ 725 Pointer: i.ErrCursor, 726 NeedICMP: true, 727 } 728 } 729 retval := IPv4OptionTimestamp(optionBody) 730 return &retval, false, nil 731 732 case IPv4OptionRecordRouteType: 733 if optLen < IPv4OptionRecordRouteHdrLength { 734 i.ErrCursor++ 735 return nil, false, &IPv4OptParameterProblem{ 736 Pointer: i.ErrCursor, 737 NeedICMP: true, 738 } 739 } 740 retval := IPv4OptionRecordRoute(optionBody) 741 return &retval, false, nil 742 743 case IPv4OptionRouterAlertType: 744 if optLen != IPv4OptionRouterAlertLength { 745 i.ErrCursor++ 746 return nil, false, &IPv4OptParameterProblem{ 747 Pointer: i.ErrCursor, 748 NeedICMP: true, 749 } 750 } 751 retval := IPv4OptionRouterAlert(optionBody) 752 return &retval, false, nil 753 } 754 retval := IPv4OptionGeneric(optionBody) 755 return &retval, false, nil 756 } 757 758 // 759 // IP Timestamp option - RFC 791 page 22. 760 // +--------+--------+--------+--------+ 761 // |01000100| length | pointer|oflw|flg| 762 // +--------+--------+--------+--------+ 763 // | internet address | 764 // +--------+--------+--------+--------+ 765 // | timestamp | 766 // +--------+--------+--------+--------+ 767 // | ... | 768 // 769 // Type = 68 770 // 771 // The Option Length is the number of octets in the option counting 772 // the type, length, pointer, and overflow/flag octets (maximum 773 // length 40). 774 // 775 // The Pointer is the number of octets from the beginning of this 776 // option to the end of timestamps plus one (i.e., it points to the 777 // octet beginning the space for next timestamp). The smallest 778 // legal value is 5. The timestamp area is full when the pointer 779 // is greater than the length. 780 // 781 // The Overflow (oflw) [4 bits] is the number of IP modules that 782 // cannot register timestamps due to lack of space. 783 // 784 // The Flag (flg) [4 bits] values are 785 // 786 // 0 -- time stamps only, stored in consecutive 32-bit words, 787 // 788 // 1 -- each timestamp is preceded with internet address of the 789 // registering entity, 790 // 791 // 3 -- the internet address fields are prespecified. An IP 792 // module only registers its timestamp if it matches its own 793 // address with the next specified internet address. 794 // 795 // Timestamps are defined in RFC 791 page 22 as milliseconds since midnight UTC. 796 // 797 // The Timestamp is a right-justified, 32-bit timestamp in 798 // milliseconds since midnight UT. If the time is not available in 799 // milliseconds or cannot be provided with respect to midnight UT 800 // then any time may be inserted as a timestamp provided the high 801 // order bit of the timestamp field is set to one to indicate the 802 // use of a non-standard value. 803 804 // IPv4OptTSFlags sefines the values expected in the Timestamp 805 // option Flags field. 806 type IPv4OptTSFlags uint8 807 808 // 809 // Timestamp option specific related constants. 810 const ( 811 // IPv4OptionTimestampHdrLength is the length of the timestamp option header. 812 IPv4OptionTimestampHdrLength = 4 813 814 // IPv4OptionTimestampSize is the size of an IP timestamp. 815 IPv4OptionTimestampSize = 4 816 817 // IPv4OptionTimestampWithAddrSize is the size of an IP timestamp + Address. 818 IPv4OptionTimestampWithAddrSize = IPv4AddressSize + IPv4OptionTimestampSize 819 820 // IPv4OptionTimestampMaxSize is limited by space for options 821 IPv4OptionTimestampMaxSize = IPv4MaximumOptionsSize 822 823 // IPv4OptionTimestampOnlyFlag is a flag indicating that only timestamp 824 // is present. 825 IPv4OptionTimestampOnlyFlag IPv4OptTSFlags = 0 826 827 // IPv4OptionTimestampWithIPFlag is a flag indicating that both timestamps and 828 // IP are present. 829 IPv4OptionTimestampWithIPFlag IPv4OptTSFlags = 1 830 831 // IPv4OptionTimestampWithPredefinedIPFlag is a flag indicating that 832 // predefined IP is present. 833 IPv4OptionTimestampWithPredefinedIPFlag IPv4OptTSFlags = 3 834 ) 835 836 // ipv4TimestampTime provides the current time as specified in RFC 791. 837 func ipv4TimestampTime(clock tcpip.Clock) uint32 { 838 // Per RFC 791 page 21: 839 // The Timestamp is a right-justified, 32-bit timestamp in 840 // milliseconds since midnight UT. 841 now := clock.Now().UTC() 842 midnight := now.Truncate(24 * time.Hour) 843 return uint32(now.Sub(midnight).Milliseconds()) 844 } 845 846 // IP Timestamp option fields. 847 const ( 848 // IPv4OptTSPointerOffset is the offset of the Timestamp pointer field. 849 IPv4OptTSPointerOffset = 2 850 851 // IPv4OptTSPointerOffset is the offset of the combined Flag and Overflow 852 // fields, (each being 4 bits). 853 IPv4OptTSOFLWAndFLGOffset = 3 854 // These constants define the sub byte fields of the Flag and OverFlow field. 855 ipv4OptionTimestampOverflowshift = 4 856 ipv4OptionTimestampFlagsMask byte = 0x0f 857 ) 858 859 var _ IPv4Option = (*IPv4OptionTimestamp)(nil) 860 861 // IPv4OptionTimestamp is a Timestamp option from RFC 791. 862 type IPv4OptionTimestamp []byte 863 864 // Type implements IPv4Option.Type(). 865 func (ts *IPv4OptionTimestamp) Type() IPv4OptionType { return IPv4OptionTimestampType } 866 867 // Size implements IPv4Option. 868 func (ts *IPv4OptionTimestamp) Size() uint8 { return uint8(len(*ts)) } 869 870 // Contents implements IPv4Option. 871 func (ts *IPv4OptionTimestamp) Contents() []byte { return *ts } 872 873 // Pointer returns the pointer field in the IP Timestamp option. 874 func (ts *IPv4OptionTimestamp) Pointer() uint8 { 875 return (*ts)[IPv4OptTSPointerOffset] 876 } 877 878 // Flags returns the flags field in the IP Timestamp option. 879 func (ts *IPv4OptionTimestamp) Flags() IPv4OptTSFlags { 880 return IPv4OptTSFlags((*ts)[IPv4OptTSOFLWAndFLGOffset] & ipv4OptionTimestampFlagsMask) 881 } 882 883 // Overflow returns the Overflow field in the IP Timestamp option. 884 func (ts *IPv4OptionTimestamp) Overflow() uint8 { 885 return (*ts)[IPv4OptTSOFLWAndFLGOffset] >> ipv4OptionTimestampOverflowshift 886 } 887 888 // IncOverflow increments the Overflow field in the IP Timestamp option. It 889 // returns the incremented value. If the return value is 0 then the field 890 // overflowed. 891 func (ts *IPv4OptionTimestamp) IncOverflow() uint8 { 892 (*ts)[IPv4OptTSOFLWAndFLGOffset] += 1 << ipv4OptionTimestampOverflowshift 893 return ts.Overflow() 894 } 895 896 // UpdateTimestamp updates the fields of the next free timestamp slot. 897 func (ts *IPv4OptionTimestamp) UpdateTimestamp(addr tcpip.Address, clock tcpip.Clock) { 898 slot := (*ts)[ts.Pointer()-1:] 899 900 switch ts.Flags() { 901 case IPv4OptionTimestampOnlyFlag: 902 binary.BigEndian.PutUint32(slot, ipv4TimestampTime(clock)) 903 (*ts)[IPv4OptTSPointerOffset] += IPv4OptionTimestampSize 904 case IPv4OptionTimestampWithIPFlag: 905 if n := copy(slot, addr); n != IPv4AddressSize { 906 panic(fmt.Sprintf("copied %d bytes, expected %d bytes", n, IPv4AddressSize)) 907 } 908 binary.BigEndian.PutUint32(slot[IPv4AddressSize:], ipv4TimestampTime(clock)) 909 (*ts)[IPv4OptTSPointerOffset] += IPv4OptionTimestampWithAddrSize 910 case IPv4OptionTimestampWithPredefinedIPFlag: 911 if tcpip.Address(slot[:IPv4AddressSize]) == addr { 912 binary.BigEndian.PutUint32(slot[IPv4AddressSize:], ipv4TimestampTime(clock)) 913 (*ts)[IPv4OptTSPointerOffset] += IPv4OptionTimestampWithAddrSize 914 } 915 } 916 } 917 918 // RecordRoute option specific related constants. 919 // 920 // from RFC 791 page 20: 921 // Record Route 922 // 923 // +--------+--------+--------+---------//--------+ 924 // |00000111| length | pointer| route data | 925 // +--------+--------+--------+---------//--------+ 926 // Type=7 927 // 928 // The record route option provides a means to record the route of 929 // an internet datagram. 930 // 931 // The option begins with the option type code. The second octet 932 // is the option length which includes the option type code and the 933 // length octet, the pointer octet, and length-3 octets of route 934 // data. The third octet is the pointer into the route data 935 // indicating the octet which begins the next area to store a route 936 // address. The pointer is relative to this option, and the 937 // smallest legal value for the pointer is 4. 938 const ( 939 // IPv4OptionRecordRouteHdrLength is the length of the Record Route option 940 // header. 941 IPv4OptionRecordRouteHdrLength = 3 942 943 // IPv4OptRRPointerOffset is the offset to the pointer field in an RR 944 // option, which points to the next free slot in the list of addresses. 945 IPv4OptRRPointerOffset = 2 946 ) 947 948 var _ IPv4Option = (*IPv4OptionRecordRoute)(nil) 949 950 // IPv4OptionRecordRoute is an IPv4 RecordRoute option defined by RFC 791. 951 type IPv4OptionRecordRoute []byte 952 953 // Pointer returns the pointer field in the IP RecordRoute option. 954 func (rr *IPv4OptionRecordRoute) Pointer() uint8 { 955 return (*rr)[IPv4OptRRPointerOffset] 956 } 957 958 // StoreAddress stores the given IPv4 address into the next free slot. 959 func (rr *IPv4OptionRecordRoute) StoreAddress(addr tcpip.Address) { 960 start := rr.Pointer() - 1 // A one based number. 961 // start and room checked by caller. 962 if n := copy((*rr)[start:], addr); n != IPv4AddressSize { 963 panic(fmt.Sprintf("copied %d bytes, expected %d bytes", n, IPv4AddressSize)) 964 } 965 (*rr)[IPv4OptRRPointerOffset] += IPv4AddressSize 966 } 967 968 // Type implements IPv4Option. 969 func (rr *IPv4OptionRecordRoute) Type() IPv4OptionType { return IPv4OptionRecordRouteType } 970 971 // Size implements IPv4Option. 972 func (rr *IPv4OptionRecordRoute) Size() uint8 { return uint8(len(*rr)) } 973 974 // Contents implements IPv4Option. 975 func (rr *IPv4OptionRecordRoute) Contents() []byte { return *rr } 976 977 // Router Alert option specific related constants. 978 // 979 // from RFC 2113 section 2.1: 980 // 981 // +--------+--------+--------+--------+ 982 // |10010100|00000100| 2 octet value | 983 // +--------+--------+--------+--------+ 984 // 985 // Type: 986 // Copied flag: 1 (all fragments must carry the option) 987 // Option class: 0 (control) 988 // Option number: 20 (decimal) 989 // 990 // Length: 4 991 // 992 // Value: A two octet code with the following values: 993 // 0 - Router shall examine packet 994 // 1-65535 - Reserved 995 const ( 996 // IPv4OptionRouterAlertLength is the length of a Router Alert option. 997 IPv4OptionRouterAlertLength = 4 998 999 // IPv4OptionRouterAlertValue is the only permissible value of the 16 bit 1000 // payload of the router alert option. 1001 IPv4OptionRouterAlertValue = 0 1002 1003 // IPv4OptionRouterAlertValueOffset is the offset for the value of a 1004 // RouterAlert option. 1005 IPv4OptionRouterAlertValueOffset = 2 1006 ) 1007 1008 var _ IPv4Option = (*IPv4OptionRouterAlert)(nil) 1009 1010 // IPv4OptionRouterAlert is an IPv4 RouterAlert option defined by RFC 2113. 1011 type IPv4OptionRouterAlert []byte 1012 1013 // Type implements IPv4Option. 1014 func (*IPv4OptionRouterAlert) Type() IPv4OptionType { return IPv4OptionRouterAlertType } 1015 1016 // Size implements IPv4Option. 1017 func (ra *IPv4OptionRouterAlert) Size() uint8 { return uint8(len(*ra)) } 1018 1019 // Contents implements IPv4Option. 1020 func (ra *IPv4OptionRouterAlert) Contents() []byte { return *ra } 1021 1022 // Value returns the value of the IPv4OptionRouterAlert. 1023 func (ra *IPv4OptionRouterAlert) Value() uint16 { 1024 return binary.BigEndian.Uint16(ra.Contents()[IPv4OptionRouterAlertValueOffset:]) 1025 } 1026 1027 // IPv4SerializableOption is an interface to represent serializable IPv4 option 1028 // types. 1029 type IPv4SerializableOption interface { 1030 // optionType returns the type identifier of the option. 1031 optionType() IPv4OptionType 1032 } 1033 1034 // IPv4SerializableOptionPayload is an interface providing serialization of the 1035 // payload of an IPv4 option. 1036 type IPv4SerializableOptionPayload interface { 1037 // length returns the size of the payload. 1038 length() uint8 1039 1040 // serializeInto serializes the payload into the provided byte buffer. 1041 // 1042 // Note, the caller MUST provide a byte buffer with size of at least 1043 // Length. Implementers of this function may assume that the byte buffer 1044 // is of sufficient size. serializeInto MUST panic if the provided byte 1045 // buffer is not of sufficient size. 1046 // 1047 // serializeInto will return the number of bytes that was used to 1048 // serialize the receiver. Implementers must only use the number of 1049 // bytes required to serialize the receiver. Callers MAY provide a 1050 // larger buffer than required to serialize into. 1051 serializeInto(buffer []byte) uint8 1052 } 1053 1054 // IPv4OptionsSerializer is a serializer for IPv4 options. 1055 type IPv4OptionsSerializer []IPv4SerializableOption 1056 1057 // Length returns the total number of bytes required to serialize the options. 1058 func (s IPv4OptionsSerializer) Length() uint8 { 1059 var total uint8 1060 for _, opt := range s { 1061 total++ 1062 if withPayload, ok := opt.(IPv4SerializableOptionPayload); ok { 1063 // Add 1 to reported length to account for the length byte. 1064 total += 1 + withPayload.length() 1065 } 1066 } 1067 return padIPv4OptionsLength(total) 1068 } 1069 1070 // Serialize serializes the provided list of IPV4 options into b. 1071 // 1072 // Note, b must be of sufficient size to hold all the options in s. See 1073 // IPv4OptionsSerializer.Length for details on the getting the total size 1074 // of a serialized IPv4OptionsSerializer. 1075 // 1076 // Serialize panics if b is not of sufficient size to hold all the options in s. 1077 func (s IPv4OptionsSerializer) Serialize(b []byte) uint8 { 1078 var total uint8 1079 for _, opt := range s { 1080 ty := opt.optionType() 1081 if withPayload, ok := opt.(IPv4SerializableOptionPayload); ok { 1082 // Serialize first to reduce bounds checks. 1083 l := 2 + withPayload.serializeInto(b[2:]) 1084 b[0] = byte(ty) 1085 b[1] = l 1086 b = b[l:] 1087 total += l 1088 continue 1089 } 1090 // Options without payload consist only of the type field. 1091 // 1092 // NB: Repeating code from the branch above is intentional to minimize 1093 // bounds checks. 1094 b[0] = byte(ty) 1095 b = b[1:] 1096 total++ 1097 } 1098 1099 // According to RFC 791: 1100 // 1101 // The internet header padding is used to ensure that the internet 1102 // header ends on a 32 bit boundary. The padding is zero. 1103 padded := padIPv4OptionsLength(total) 1104 b = b[:padded-total] 1105 for i := range b { 1106 b[i] = 0 1107 } 1108 return padded 1109 } 1110 1111 var _ IPv4SerializableOptionPayload = (*IPv4SerializableRouterAlertOption)(nil) 1112 var _ IPv4SerializableOption = (*IPv4SerializableRouterAlertOption)(nil) 1113 1114 // IPv4SerializableRouterAlertOption provides serialization of the Router Alert 1115 // IPv4 option according to RFC 2113. 1116 type IPv4SerializableRouterAlertOption struct{} 1117 1118 // Type implements IPv4SerializableOption. 1119 func (*IPv4SerializableRouterAlertOption) optionType() IPv4OptionType { 1120 return IPv4OptionRouterAlertType 1121 } 1122 1123 // Length implements IPv4SerializableOption. 1124 func (*IPv4SerializableRouterAlertOption) length() uint8 { 1125 return IPv4OptionRouterAlertLength - IPv4OptionRouterAlertValueOffset 1126 } 1127 1128 // SerializeInto implements IPv4SerializableOption. 1129 func (o *IPv4SerializableRouterAlertOption) serializeInto(buffer []byte) uint8 { 1130 binary.BigEndian.PutUint16(buffer, IPv4OptionRouterAlertValue) 1131 return o.length() 1132 } 1133 1134 var _ IPv4SerializableOption = (*IPv4SerializableNOPOption)(nil) 1135 1136 // IPv4SerializableNOPOption provides serialization for the IPv4 no-op option. 1137 type IPv4SerializableNOPOption struct{} 1138 1139 // Type implements IPv4SerializableOption. 1140 func (*IPv4SerializableNOPOption) optionType() IPv4OptionType { 1141 return IPv4OptionNOPType 1142 } 1143 1144 var _ IPv4SerializableOption = (*IPv4SerializableListEndOption)(nil) 1145 1146 // IPv4SerializableListEndOption provides serialization for the IPv4 List End 1147 // option. 1148 type IPv4SerializableListEndOption struct{} 1149 1150 // Type implements IPv4SerializableOption. 1151 func (*IPv4SerializableListEndOption) optionType() IPv4OptionType { 1152 return IPv4OptionListEndType 1153 }