package ipv4 import ( "strconv" ) const ( // RFC791 defines the minimum MTU for an IPv4 packet as 68, meaning a payload of 48 bytes when no IPv4 options included. MinimumMTU = 68 sizeHeader = 20 ) // IsMulticast reports whether addr is an IPv4 multicast address (224.0.0.0/4), // i.e. the most significant nibble is 0xE (1110 in binary) as defined in [RFC1112]. // // [RFC1112]: https://datatracker.ietf.org/doc/html/rfc1112 func IsMulticast(addr [4]byte) bool { return addr[0]&0xf0 == 0xe0 } // ToS represents the Traffic Class (a.k.a Type of Service). It is 8 bits long. 6 MSB are Differentiated Services; 2 LSB are Explicit Congenstion Notification. type ToS uint8 // NewToS returns a [ToS] from an Explicit Congestion Notification value and a Differentiated Services Field value. func NewToS(ECN, DS uint8) ToS { if ECN > 0b11 || DS > 0b11_1111 { panic("invalid ECN/DS value") } return ToS(ECN | (DS << 2)) } // DS returns the top 6 bits of the IPv4 ToS holding the Differentiated Services field // which is used to classify packets. func (tos ToS) DS() uint8 { return uint8(tos) >> 2 } // ECN is the Explicit Congestion Notification which provides congestion control and non-congestion control traffic. func (tos ToS) ECN() uint8 { return uint8(tos & 0b11) } // Flags holds fragmentation field data of an IPv4 header. It is 16 bits long. type Flags uint16 const ( flagIsEvilPos = 13 flagDontFragPos = 14 flagMoreFragPos = 15 FlagOffsetMask = (1 << flagIsEvilPos) - 1 flagIsEvil Flags = 1 << flagIsEvilPos FlagDontFragment Flags = 1 << flagDontFragPos FlagMoreFragments Flags = 1 << flagMoreFragPos ) func NewFlags(fragOffset uint16, dontFrag, moreFrag bool) Flags { if fragOffset > FlagOffsetMask { panic("invalid NewFlags arg") } return Flags(fragOffset) | Flags(b2u8(dontFrag))<