tcp报文头结构可视化解析;优化IP udp报文的可视化解析

This commit is contained in:
impact-eintr
2022-12-05 18:20:21 +08:00
parent f3ceda183b
commit c7fe592b0f
12 changed files with 665 additions and 46 deletions

View File

@@ -180,6 +180,16 @@ func (b IPv4) Payload() []byte {
return b[b.HeaderLength():][:b.PayloadLength()]
}
// IPViewSize IP报文内容概览 长度
const IPViewSize = 128
func (b IPv4) viewPayload() []byte {
if b.PayloadLength() < IPViewSize {
return b[b.HeaderLength():][:b.PayloadLength()]
}
return b[b.HeaderLength():][:IPViewSize]
}
// PayloadLength returns the length of the payload portion of the ipv4 packet.
func (b IPv4) PayloadLength() uint16 {
return b.TotalLength() - uint16(b.HeaderLength())
@@ -294,20 +304,10 @@ func atoi[T int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32]
}
func (b IPv4) String() string {
for i := range b.Payload() {
if i != int(b.PayloadLength()-1) && b.Payload()[i]^b.Payload()[i+1] != 0 {
return fmt.Sprintf(ipv4Fmt, atoi(IPVersion(b)), atoi(b.HeaderLength()), atoi(0), atoi(b.TotalLength()),
atoi(b.ID()), atoi(b.Flags()>>2), atoi((b.Flags()&2)>>1), atoi(b.Flags()&1), atoi(b.FragmentOffset()),
atoi(b.TTL()), atoi(b.Protocol()), atoi(b.Checksum()),
b.SourceAddress().String(),
b.DestinationAddress().String(),
b.Payload())
}
}
return fmt.Sprintf(ipv4Fmt, atoi(IPVersion(b)), atoi(b.HeaderLength()), atoi(0), atoi(b.TotalLength()),
atoi(b.ID()), atoi(b.Flags()>>2), atoi((b.Flags()&2)>>1), atoi(b.Flags()&1), atoi(b.FragmentOffset()),
atoi(b.TTL()), atoi(b.Protocol()), atoi(b.Checksum()),
b.SourceAddress().String(),
b.DestinationAddress().String(),
fmt.Sprintf("%v x %d", b.Payload()[0], b.PayloadLength()))
b.viewPayload())
}

View File

@@ -2,6 +2,7 @@ package header
import (
"encoding/binary"
"fmt"
"netstack/tcpip"
)
@@ -91,3 +92,114 @@ func (b TCP) SourcePort() uint16 {
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())
}

View File

@@ -77,6 +77,16 @@ func (b UDP) Payload() []byte {
return b[UDPMinimumSize:]
}
// UDPViewSize UDP报文内容概览 长度
const UDPViewSize = IPViewSize - UDPMinimumSize
func (b UDP) viewPayload() []byte {
if b.Length()-UDPMinimumSize < UDPViewSize {
return b[UDPMinimumSize:]
}
return b[UDPMinimumSize:][:UDPViewSize]
}
// Checksum returns the "checksum" field of the udp header.
func (b UDP) Checksum() uint16 {
return binary.BigEndian.Uint16(b[udpChecksum:])
@@ -125,14 +135,7 @@ var udpFmt string = `
`
func (b UDP) String() string {
for i := range b.Payload() {
if i != int(b.Length()-8-1) && b.Payload()[i]^b.Payload()[i+1] != 0 {
return fmt.Sprintf(udpFmt, atoi(b.SourcePort()), atoi(b.DestinationPort()),
atoi(b.Length()), atoi(b.Checksum()),
b.Payload())
}
}
return fmt.Sprintf(udpFmt, atoi(b.SourcePort()), atoi(b.DestinationPort()),
atoi(b.Length()), atoi(b.Checksum()),
fmt.Sprintf("%v x %d", b.Payload()[0], b.Length()-8))
b.viewPayload())
}