func (b TCP) EncodePartial(partialChecksum, length uint16, seqnum, acknum uint32, flags byte, rcvwnd uint16) {
	tmp := make([]byte, 4)
	binary.BigEndian.PutUint16(tmp, length)
	binary.BigEndian.PutUint16(tmp[2:], uint16(flags))
	checksum := Checksum(tmp, partialChecksum)
	b.encodeSubset(seqnum, acknum, flags, rcvwnd)
	checksum = Checksum(b[TCPSeqNumOffset:TCPSeqNumOffset+8], checksum)
	checksum = Checksum(b[TCPWinSizeOffset:TCPWinSizeOffset+2], checksum)
	b.SetChecksum(^checksum)
}
EncodePartial updates a subset of the fields of the tcp header. It is useful
in cases when similar segments are produced.
package header
import (
	"encoding/binary"
	"github.com/google/btree"
	"github.com/google/netstack/tcpip"
	"github.com/google/netstack/tcpip/seqnum"
)
const (
	TCPSrcPortOffset   = 0
	TCPDstPortOffset   = 2
	TCPSeqNumOffset    = 4
	TCPAckNumOffset    = 8
	TCPDataOffset      = 12
	TCPFlagsOffset     = 13
	TCPWinSizeOffset   = 14
	TCPChecksumOffset  = 16
	TCPUrgentPtrOffset = 18
)
const (
	MaxWndScale = 14
	TCPMaxSACKBlocks = 4
)
const (
	TCPFlagFin = 1 << iota
	TCPFlagSyn
	TCPFlagRst
	TCPFlagPsh
	TCPFlagAck
	TCPFlagUrg
)
const (
	TCPOptionEOL           = 0
	TCPOptionNOP           = 1
	TCPOptionMSS           = 2
	TCPOptionWS            = 3
	TCPOptionTS            = 8
	TCPOptionSACKPermitted = 4
	TCPOptionSACK          = 5
)
type TCPFields struct {
	SrcPort uint16
	DstPort uint16
	SeqNum uint32
	AckNum uint32
	DataOffset uint8
	Flags uint8
	WindowSize uint16
	Checksum uint16
	UrgentPointer uint16
}
type TCPSynOptions struct {
	MSS uint16
	WS int
	TS bool
	TSVal uint32
	TSEcr uint32
	SACKPermitted bool
}
type SACKBlock struct {
	Start seqnum.Value
	End seqnum.Value
}
func (r SACKBlock) Less(b btree.Item) bool {
	return r.Start.LessThan(b.(SACKBlock).Start)
}
func (r SACKBlock) Contains(b SACKBlock) bool {
	return r.Start.LessThanEq(b.Start) && b.End.LessThanEq(r.End)
}
type TCPOptions struct {
	TS bool
	TSVal uint32
	TSEcr uint32
	SACKBlocks []SACKBlock
}
type TCP []byte
const (
	TCPMinimumSize = 20
	TCPOptionsMaximumSize = 40
	TCPHeaderMaximumSize = TCPMinimumSize + TCPOptionsMaximumSize
	TCPProtocolNumber tcpip.TransportProtocolNumber = 6
	TCPMinimumMSS = IPv4MaximumHeaderSize + TCPHeaderMaximumSize + MinIPFragmentPayloadSize - IPv4MinimumSize - TCPMinimumSize
	TCPMaximumMSS = 0xffff
	TCPDefaultMSS = 536
)
func (b TCP) SourcePort() uint16 {
	return binary.BigEndian.Uint16(b[TCPSrcPortOffset:])
}
func (b TCP) DestinationPort() uint16 {
	return binary.BigEndian.Uint16(b[TCPDstPortOffset:])
}
func (b TCP) SequenceNumber() uint32 {
	return binary.BigEndian.Uint32(b[TCPSeqNumOffset:])
}
func (b TCP) AckNumber() uint32 {
	return binary.BigEndian.Uint32(b[TCPAckNumOffset:])
}
func (b TCP) DataOffset() uint8 {
	return (b[TCPDataOffset] >> 4) * 4
}
func (b TCP) Payload() []byte {
	return b[b.DataOffset():]
}
func (b TCP) Flags() uint8 {
	return b[TCPFlagsOffset]
}
func (b TCP) WindowSize() uint16 {
	return binary.BigEndian.Uint16(b[TCPWinSizeOffset:])
}
func (b TCP) Checksum() uint16 {
	return binary.BigEndian.Uint16(b[TCPChecksumOffset:])
}
func (b TCP) SetSourcePort(port uint16) {
	binary.BigEndian.PutUint16(b[TCPSrcPortOffset:], port)
}
func (b TCP) SetDestinationPort(port uint16) {
	binary.BigEndian.PutUint16(b[TCPDstPortOffset:], port)
}
func (b TCP) SetChecksum(checksum uint16) {
	binary.BigEndian.PutUint16(b[TCPChecksumOffset:], checksum)
}
func (b TCP) CalculateChecksum(partialChecksum uint16) uint16 {
	return Checksum(b[:b.DataOffset()], partialChecksum)
}
func (b TCP) Options() []byte {
	return b[TCPMinimumSize:b.DataOffset()]
}
func (b TCP) ParsedOptions() TCPOptions {
	return ParseTCPOptions(b.Options())
}
func (b TCP) encodeSubset(seq, ack uint32, flags uint8, rcvwnd uint16) {
	binary.BigEndian.PutUint32(b[TCPSeqNumOffset:], seq)
	binary.BigEndian.PutUint32(b[TCPAckNumOffset:], ack)
	b[TCPFlagsOffset] = flags
	binary.BigEndian.PutUint16(b[TCPWinSizeOffset:], rcvwnd)
}
func (b TCP) Encode(t *TCPFields) {
	b.encodeSubset(t.SeqNum, t.AckNum, t.Flags, t.WindowSize)
	binary.BigEndian.PutUint16(b[TCPSrcPortOffset:], t.SrcPort)
	binary.BigEndian.PutUint16(b[TCPDstPortOffset:], t.DstPort)
	b[TCPDataOffset] = (t.DataOffset / 4) << 4
	binary.BigEndian.PutUint16(b[TCPChecksumOffset:], t.Checksum)
	binary.BigEndian.PutUint16(b[TCPUrgentPtrOffset:], t.UrgentPointer)
}