github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/protocol/tcp.go (about)

     1  package protocol
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  )
     7  
     8  type TCP struct {
     9  	PortSrc uint16
    10  	PortDst uint16
    11  	SeqNum  uint32
    12  	AckNum  uint32
    13  
    14  	HdrLen uint8
    15  	Code   uint8
    16  
    17  	WinSize  uint16
    18  	Checksum uint16
    19  	UrgFlag  uint16
    20  
    21  	Data []byte
    22  }
    23  
    24  func NewTCP() *TCP {
    25  	u := new(TCP)
    26  	u.Data = make([]byte, 0)
    27  	return u
    28  }
    29  
    30  func (t *TCP) Len() (n uint16) {
    31  	if t.Data != nil {
    32  		return uint16(20 + len(t.Data))
    33  	}
    34  	return uint16(20)
    35  }
    36  
    37  func (t *TCP) MarshalBinary() (data []byte, err error) {
    38  	data = make([]byte, int(t.Len()))
    39  	binary.BigEndian.PutUint16(data[:2], t.PortSrc)
    40  	binary.BigEndian.PutUint16(data[2:4], t.PortDst)
    41  	binary.BigEndian.PutUint32(data[4:8], t.SeqNum)
    42  	binary.BigEndian.PutUint32(data[8:12], t.AckNum)
    43  
    44  	data[12] = (t.HdrLen << 4) & 0xf0
    45  	data[13] = t.Code & 0x3f
    46  
    47  	binary.BigEndian.PutUint16(data[14:16], t.WinSize)
    48  	binary.BigEndian.PutUint16(data[16:18], t.Checksum)
    49  	binary.BigEndian.PutUint16(data[18:20], t.UrgFlag)
    50  
    51  	copy(data[20:], t.Data)
    52  
    53  	return
    54  }
    55  
    56  func (t *TCP) UnmarshalBinary(data []byte) error {
    57  	if len(data) < 20 {
    58  		return errors.New("The []byte is too short to unmarshal a full ARP message.")
    59  	}
    60  	t.PortSrc = binary.BigEndian.Uint16(data[:2])
    61  	t.PortDst = binary.BigEndian.Uint16(data[2:4])
    62  	t.SeqNum = binary.BigEndian.Uint32(data[4:8])
    63  	t.AckNum = binary.BigEndian.Uint32(data[8:12])
    64  
    65  	t.HdrLen = (data[12] >> 4) & 0xf
    66  	t.Code = data[13] & 0x3f
    67  
    68  	t.WinSize = binary.BigEndian.Uint16(data[14:16])
    69  	t.Checksum = binary.BigEndian.Uint16(data[16:18])
    70  	t.UrgFlag = binary.BigEndian.Uint16(data[18:20])
    71  
    72  	if len(data) > 20 {
    73  		t.Data = make([]byte, (len(data) - 20))
    74  		copy(t.Data, data[20:])
    75  	}
    76  
    77  	return nil
    78  
    79  }