mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-05 12:56:55 +08:00
206 lines
6.5 KiB
Go
206 lines
6.5 KiB
Go
package header
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"netstack/tcpip"
|
|
)
|
|
|
|
/*
|
|
0 1 2 3
|
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Source Port | Destination Port |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Sequence Number |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Acknowledgment Number |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Data | |U|A|P|R|S|F| |
|
|
| Offset| Reserved |R|C|S|S|Y|I| Window |
|
|
| | |G|K|H|T|N|N| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Checksum | Urgent Pointer |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Options | Padding |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| data |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
*/
|
|
|
|
// TCPFields contains the fields of a TCP packet. It is used to describe the
|
|
// fields of a packet that needs to be encoded.
|
|
// tcp首部字段
|
|
type TCPFields struct {
|
|
// SrcPort is the "source port" field of a TCP packet.
|
|
SrcPort uint16
|
|
|
|
// DstPort is the "destination port" field of a TCP packet.
|
|
DstPort uint16
|
|
|
|
// SeqNum is the "sequence number" field of a TCP packet.
|
|
SeqNum uint32
|
|
|
|
// AckNum is the "acknowledgement number" field of a TCP packet.
|
|
AckNum uint32
|
|
|
|
// DataOffset is the "data offset" field of a TCP packet.
|
|
DataOffset uint8
|
|
|
|
// Flags is the "flags" field of a TCP packet.
|
|
Flags uint8
|
|
|
|
// WindowSize is the "window size" field of a TCP packet.
|
|
WindowSize uint16
|
|
|
|
// Checksum is the "checksum" field of a TCP packet.
|
|
Checksum uint16
|
|
|
|
// UrgentPointer is the "urgent pointer" field of a TCP packet.
|
|
UrgentPointer uint16
|
|
}
|
|
|
|
const (
|
|
srcPort = 0
|
|
dstPort = 2
|
|
seqNum = 4
|
|
ackNum = 8
|
|
dataOffset = 12
|
|
tcpFlags = 13
|
|
winSize = 14
|
|
tcpChecksum = 16
|
|
urgentPtr = 18
|
|
)
|
|
|
|
// TCP represents a TCP header stored in a byte array.
|
|
type TCP []byte
|
|
|
|
const (
|
|
// TCPMinimumSize is the minimum size of a valid TCP packet.
|
|
TCPMinimumSize = 20
|
|
|
|
// TCPProtocolNumber is TCP's transport protocol number.
|
|
TCPProtocolNumber tcpip.TransportProtocolNumber = 6
|
|
)
|
|
|
|
// SourcePort returns the "source port" field of the tcp header.
|
|
func (b TCP) SourcePort() uint16 {
|
|
return binary.BigEndian.Uint16(b[srcPort:])
|
|
}
|
|
|
|
// DestinationPort returns the "destination port" field of the tcp header.
|
|
func (b TCP) DestinationPort() uint16 {
|
|
return binary.BigEndian.Uint16(b[dstPort:])
|
|
}
|
|
|
|
// SequenceNumber returns the "sequence number" field of the tcp header.
|
|
func (b TCP) SequenceNumber() uint32 {
|
|
return binary.BigEndian.Uint32(b[seqNum:])
|
|
}
|
|
|
|
// AckNumber returns the "ack number" field of the tcp header.
|
|
func (b TCP) AckNumber() uint32 {
|
|
return binary.BigEndian.Uint32(b[ackNum:])
|
|
}
|
|
|
|
// DataOffset returns the "data offset" field of the tcp header.
|
|
func (b TCP) DataOffset() uint8 {
|
|
return (b[dataOffset] >> 4) * 4 // 以32bits为单位 最小为5 20bytes
|
|
}
|
|
|
|
// Payload returns the data in the tcp packet.
|
|
func (b TCP) Payload() []byte {
|
|
return b[b.DataOffset():]
|
|
}
|
|
|
|
// TCPViewSize TCP报文概览长度
|
|
const TCPViewSize = IPViewSize - TCPMinimumSize
|
|
|
|
func (b TCP) viewPayload() []byte {
|
|
if len(b.Payload())-int(b.DataOffset()) < TCPViewSize {
|
|
return b.Payload()
|
|
}
|
|
return b[b.DataOffset():][:TCPViewSize]
|
|
}
|
|
|
|
// Flags returns the flags field of the tcp header.
|
|
func (b TCP) Flags() uint8 {
|
|
return b[tcpFlags]
|
|
}
|
|
|
|
// WindowSize returns the "window size" field of the tcp header.
|
|
func (b TCP) WindowSize() uint16 {
|
|
return binary.BigEndian.Uint16(b[winSize:])
|
|
}
|
|
|
|
// Checksum returns the "checksum" field of the tcp header.
|
|
func (b TCP) Checksum() uint16 {
|
|
return binary.BigEndian.Uint16(b[tcpChecksum:])
|
|
}
|
|
|
|
// UrgentPtr returns the "urgentptr" field of the tcp header.
|
|
func (b TCP) UrgentPtr() uint16 {
|
|
return binary.BigEndian.Uint16(b[urgentPtr:])
|
|
}
|
|
|
|
// SetSourcePort sets the "source port" field of the tcp header.
|
|
func (b TCP) SetSourcePort(port uint16) {
|
|
binary.BigEndian.PutUint16(b[srcPort:], port)
|
|
}
|
|
|
|
// SetDestinationPort sets the "destination port" field of the tcp header.
|
|
func (b TCP) SetDestinationPort(port uint16) {
|
|
binary.BigEndian.PutUint16(b[dstPort:], port)
|
|
}
|
|
|
|
// SetChecksum sets the checksum field of the tcp header.
|
|
func (b TCP) SetChecksum(checksum uint16) {
|
|
binary.BigEndian.PutUint16(b[tcpChecksum:], checksum)
|
|
}
|
|
|
|
// Options returns a slice that holds the unparsed TCP options in the segment.
|
|
func (b TCP) Options() []byte {
|
|
return b[TCPMinimumSize:b.DataOffset()]
|
|
}
|
|
|
|
/*
|
|
0 1 2 3
|
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Source Port | Destination Port |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Sequence Number |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Acknowledgment Number |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Data | |U|A|P|R|S|F| |
|
|
| Offset| Reserved |R|C|S|S|Y|I| Window |
|
|
| | |G|K|H|T|N|N| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Checksum | Urgent Pointer |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Options | Padding |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| data |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
*/
|
|
|
|
var tcpFmt string = `
|
|
|% 16s|% 16s|
|
|
|% 32s |
|
|
|% 32s |
|
|
|% 4s|% 4s|%06b|% 16s|
|
|
|% 16s|% 16s|
|
|
| Options | Padding |
|
|
%v
|
|
`
|
|
|
|
func (b TCP) String() string {
|
|
return fmt.Sprintf(tcpFmt, atoi(b.SourcePort()), atoi(b.DestinationPort()),
|
|
atoi(b.SequenceNumber()),
|
|
atoi(b.AckNumber()),
|
|
atoi(b.DataOffset()), "0", b.Flags(), atoi(b.WindowSize()),
|
|
atoi(b.Checksum()), atoi(b.UrgentPtr()),
|
|
b.viewPayload())
|
|
}
|