github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/ipv4/packet.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package ipv4 4 5 import ( 6 "../binary" 7 "../protocol" 8 ) 9 10 // Packet implement all methods to Get||Set data to a packet as a byte slice with 0-alloc 11 type Packet []byte 12 13 // CheckPacket checks packet for any bad situation 14 // Always check packet before use any other packet methods otherwise panic may occur 15 func (p Packet) CheckPacket() protocol.Error { 16 var packetLen = len(p) 17 if packetLen < HeaderLen { 18 return ErrPacketTooShort 19 } 20 if packetLen < int(p.IHL()) { 21 return ErrPacketWrongLength 22 } 23 return nil 24 } 25 26 /* 27 ********** Get Methods ********** 28 */ 29 func (p Packet) Version() uint8 { return p[0] >> 4 } 30 func (p Packet) IHL() uint8 { return (p[0] & 0x0f) * 4 } 31 func (p Packet) DSCP() uint8 { return p[1] >> 2 } 32 func (p Packet) TotalLength() uint16 { return binary.BigEndian.Uint16(p[2:]) } 33 func (p Packet) Identification() (id [2]byte) { copy(id[:], p[4:]); return } 34 func (p Packet) FragmentOffset() uint16 { return binary.BigEndian.Uint16(p[6:]) & 0b1110000000000000 } 35 func (p Packet) TimeToLive() uint8 { return p[8] } 36 func (p Packet) Protocol() uint8 { return p[9] } 37 func (p Packet) HeaderChecksum() (check [2]byte) { copy(check[:], p[10:]); return } 38 func (p Packet) SourceAddr() (srcAddr Addr) { copy(srcAddr[:], p[12:]); return } 39 func (p Packet) DestinationAddr() (desAddr Addr) { copy(desAddr[:], p[16:]); return } 40 func (p Packet) Options() []byte { return p[20:] } 41 func (p Packet) Payload() []byte { return p[p.IHL():] } 42 43 /* 44 ********** Set Methods ********** 45 */ 46 func (p Packet) SetVersion(v uint8) { p[0] = (v << 4) } 47 func (p Packet) SetIHL(ln uint8) { p[0] |= (ln / 4) } 48 func (p Packet) SetDSCP(dscp uint8) { p[1] |= (dscp >> 2) } 49 func (p Packet) SetTotalLength(tl uint16) { binary.BigEndian.SetUint16(p[2:], tl) } 50 func (p Packet) SetIdentification(id [2]byte) { copy(p[4:], id[:]) } 51 func (p Packet) SetFragmentOffset(fo uint16) { binary.BigEndian.SetUint16(p[6:], fo) } 52 func (p Packet) SetTimeToLive(ttl uint8) { p[8] = ttl } 53 func (p Packet) SetProtocol(proto uint8) { p[9] = proto } 54 func (p Packet) SetHeaderChecksum(check [2]byte) { copy(p[10:], check[:]); return } 55 func (p Packet) SetSourceAddr(srcAddr Addr) { copy(p[12:], srcAddr[:]); return } 56 func (p Packet) SetDestinationAddr(desAddr Addr) { copy(p[16:], desAddr[:]); return } 57 func (p Packet) SetOptions(opts []byte) { copy(p[20:], opts) } 58 func (p Packet) SetPayload(payload []byte) { copy(p[p.IHL():], payload) } 59 60 /* 61 ********** Flags ********** 62 */ 63 func (p Packet) FlagECT() bool { return p.FlagECT0() || p.FlagECT1() } 64 func (p Packet) FlagECT0() bool { return p[1]&Flag_ECT0 != 0 } 65 func (p Packet) FlagECT1() bool { return p[1]&Flag_ECT1 != 0 } 66 func (p Packet) FlagCE() bool { return p[1]&Flag_CE != 0 } 67 func (p Packet) FlagReserved() bool { return p[6]&Flag_Reserved != 0 } 68 func (p Packet) FlagDF() bool { return p[6]&Flag_DF != 0 } 69 func (p Packet) FlagMF() bool { return p[6]&Flag_MF != 0 } 70 71 func (p Packet) SetFlagECT() { p.SetFlagECT0() } 72 func (p Packet) SetFlagECT0() { p[1] |= Flag_ECT0 } 73 func (p Packet) SetFlagECT1() { p[1] |= Flag_ECT1 } 74 func (p Packet) SetFlagCE() { p[1] |= Flag_CE } 75 func (p Packet) SetFlagReserved() { p[6] |= Flag_Reserved } 76 func (p Packet) SetFlagDF() { p[6] |= Flag_DF } 77 func (p Packet) SetFlagMF() { p[6] |= Flag_MF } 78 79 func (p Packet) UnsetFlagECT() { p[1] &= ^Flag_CE } 80 func (p Packet) UnsetFlagECT0() { p[1] &= ^Flag_ECT0 } 81 func (p Packet) UnsetFlagECT1() { p[1] &= ^Flag_ECT1 } 82 func (p Packet) UnsetFlagCE() { p[1] &= ^Flag_CE } 83 func (p Packet) UnsetFlagReserved() { p[6] &= ^Flag_Reserved } 84 func (p Packet) UnsetFlagDF() { p[6] &= ^Flag_DF } 85 func (p Packet) UnsetFlagMF() { p[6] &= ^Flag_MF }