github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/tcp/segment.go (about)

     1  // For license and copyright information please see the LEGAL file in the code repository
     2  
     3  package tcp
     4  
     5  import (
     6  	"github.com/GeniusesGroup/libgo/binary"
     7  	"github.com/GeniusesGroup/libgo/protocol"
     8  )
     9  
    10  // Packet implement all methods to Get||Set data to a packet as a byte slice with 0-alloc
    11  // https://datatracker.ietf.org/doc/html/rfc793#section-3.1
    12  type Packet []byte
    13  
    14  // CheckPacket will check packet for any bad situation.
    15  // Always check packet before use any other packet methods otherwise panic occur.
    16  func (p Packet) CheckPacket() protocol.Error {
    17  	var packetLen = len(p)
    18  	if packetLen < MinPacketLen {
    19  		return &ErrPacketTooShort
    20  	}
    21  	if packetLen < int(p.DataOffset()) {
    22  		return &ErrPacketWrongLength
    23  	}
    24  	return nil
    25  }
    26  
    27  /*
    28  ********** Get Methods **********
    29   */
    30  func (p Packet) SourcePort() uint16      { return binary.BigEndian.Uint16(p[0:]) }
    31  func (p Packet) DestinationPort() uint16 { return binary.BigEndian.Uint16(p[2:]) }
    32  func (p Packet) SequenceNumber() uint32  { return binary.BigEndian.Uint32(p[4:]) }
    33  func (p Packet) AckNumber() uint32       { return binary.BigEndian.Uint32(p[8:]) }
    34  func (p Packet) DataOffset() uint8       { return (p[12] >> 4) * 4 }
    35  func (p Packet) Window() uint16          { return binary.BigEndian.Uint16(p[14:]) }
    36  func (p Packet) Checksum() uint16        { return binary.BigEndian.Uint16(p[16:]) }
    37  func (p Packet) UrgentPointer() uint16   { return binary.BigEndian.Uint16(p[18:]) }
    38  func (p Packet) Options() []byte         { return p[20:p.DataOffset()] }
    39  func (p Packet) Payload() []byte         { return p[p.DataOffset():] }
    40  
    41  /*
    42  ********** Set Methods **********
    43   */
    44  func (p Packet) SetSourcePort(port uint16)      { binary.BigEndian.PutUint16(p[0:], port) }
    45  func (p Packet) SetDestinationPort(port uint16) { binary.BigEndian.PutUint16(p[2:], port) }
    46  func (p Packet) SetSequenceNumber(v uint32)     { binary.BigEndian.PutUint32(p[4:], v) }
    47  func (p Packet) SetAckNumber(v uint32)          { binary.BigEndian.PutUint32(p[8:], v) }
    48  func (p Packet) SetDataOffset(ln uint8)         { p[12] = byte((ln/4)<<4) | p[12] }
    49  func (p Packet) SetFlagPartOne(flags byte)      { p[12] = p[12] | flags }
    50  func (p Packet) SetFlagPartTwo(flags byte)      { p[13] = flags }
    51  func (p Packet) SetWindow(v uint16)             { binary.BigEndian.PutUint16(p[14:], v) }
    52  func (p Packet) SetChecksum(v uint16)           { binary.BigEndian.PutUint16(p[16:], v) }
    53  func (p Packet) SetUrgentPointer(v uint16)      { binary.BigEndian.PutUint16(p[18:], v) }
    54  func (p Packet) SetOptions(o []byte)            { copy(p[20:], o) }
    55  func (p Packet) SetPayload(payload []byte)      { copy(p[p.DataOffset():], payload) }
    56  
    57  /*
    58  ********** Flags **********
    59   */
    60  func (p Packet) FlagReserved1() bool { return p[12]&Flag_Reserved1 != 0 }
    61  func (p Packet) FlagReserved2() bool { return p[12]&Flag_Reserved2 != 0 }
    62  func (p Packet) FlagReserved3() bool { return p[12]&Flag_Reserved3 != 0 }
    63  func (p Packet) FlagNS() bool        { return p[12]&Flag_NS != 0 }
    64  func (p Packet) FlagCWR() bool       { return p[13]&Flag_CWR != 0 }
    65  func (p Packet) FlagECE() bool       { return p[13]&Flag_ECE != 0 }
    66  func (p Packet) FlagURG() bool       { return p[13]&Flag_URG != 0 }
    67  func (p Packet) FlagACK() bool       { return p[13]&Flag_ACK != 0 }
    68  func (p Packet) FlagPSH() bool       { return p[13]&Flag_PSH != 0 }
    69  func (p Packet) FlagRST() bool       { return p[13]&Flag_RST != 0 }
    70  func (p Packet) FlagSYN() bool       { return p[13]&Flag_SYN != 0 }
    71  func (p Packet) FlagFIN() bool       { return p[13]&Flag_FIN != 0 }
    72  
    73  func (p Packet) SetFlagReserved1() { p[12] |= Flag_Reserved1 }
    74  func (p Packet) SetFlagReserved2() { p[12] |= Flag_Reserved2 }
    75  func (p Packet) SetFlagReserved3() { p[12] |= Flag_Reserved3 }
    76  func (p Packet) SetFlagNS()        { p[12] |= Flag_NS }
    77  func (p Packet) SetFlagCWR()       { p[13] |= Flag_CWR }
    78  func (p Packet) SetFlagECE()       { p[13] |= Flag_ECE }
    79  func (p Packet) SetFlagURG()       { p[13] |= Flag_URG }
    80  func (p Packet) SetFlagACK()       { p[13] |= Flag_ACK }
    81  func (p Packet) SetFlagPSH()       { p[13] |= Flag_PSH }
    82  func (p Packet) SetFlagRST()       { p[13] |= Flag_RST }
    83  func (p Packet) SetFlagSYN()       { p[13] |= Flag_SYN }
    84  func (p Packet) SetFlagFIN()       { p[13] |= Flag_FIN }
    85  
    86  func (p Packet) UnsetFlagReserved1() { p[12] &= ^Flag_Reserved1 }
    87  func (p Packet) UnsetFlagReserved2() { p[12] &= ^Flag_Reserved2 }
    88  func (p Packet) UnsetFlagReserved3() { p[12] &= ^Flag_Reserved3 }
    89  func (p Packet) UnsetFlagNS()        { p[12] &= ^Flag_NS }
    90  func (p Packet) UnsetFlagCWR()       { p[13] &= ^Flag_CWR }
    91  func (p Packet) UnsetFlagECE()       { p[13] &= ^Flag_ECE }
    92  func (p Packet) UnsetFlagURG()       { p[13] &= ^Flag_URG }
    93  func (p Packet) UnsetFlagACK()       { p[13] &= ^Flag_ACK }
    94  func (p Packet) UnsetFlagPSH()       { p[13] &= ^Flag_PSH }
    95  func (p Packet) UnsetFlagRST()       { p[13] &= ^Flag_RST }
    96  func (p Packet) UnsetFlagSYN()       { p[13] &= ^Flag_SYN }
    97  func (p Packet) UnsetFlagFIN()       { p[13] &= ^Flag_FIN }