Skip to content

Commit 4bd9981

Browse files
committed
Add starting TCP support
1 parent 44c7806 commit 4bd9981

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

protocols/tcp.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package protocols
2+
3+
import (
4+
"encoding/binary"
5+
"errors"
6+
"fmt"
7+
)
8+
9+
type TCPPacket struct {
10+
ipPacket IPPacket
11+
header tcpHeader
12+
}
13+
14+
type tcpHeader struct {
15+
sourcePort uint16
16+
destinationPort uint16
17+
sequenceNumber uint32
18+
ackNumber uint32
19+
rawOffset uint8
20+
reserved uint8
21+
flags uint16
22+
windowSize uint16
23+
checksum uint16
24+
urgentPointer uint16
25+
options []byte
26+
}
27+
28+
var errTCPHeaderTooShort = errors.New("TCP header must be at least 20 bytes")
29+
var errTCPHeaderLenMismatch = errors.New("TCP header length less than raw Offset")
30+
31+
func TCPPacketFromIPPacket(ip IPPacket) (*TCPPacket, error) {
32+
tcpHeader, err := tcpHeaderFromBytes(ip.Payload())
33+
34+
return &TCPPacket{
35+
ipPacket: ip,
36+
header: *tcpHeader,
37+
}, err
38+
}
39+
40+
func tcpHeaderFromBytes(raw []byte) (*tcpHeader, error) {
41+
if len(raw) < 20 {
42+
return nil, errTCPHeaderTooShort
43+
}
44+
offset := (raw[12] >> 4)
45+
hLen := int(offset * 4)
46+
if len(raw) < hLen {
47+
return nil, errTCPHeaderLenMismatch
48+
}
49+
return &tcpHeader{
50+
sourcePort: binary.BigEndian.Uint16(raw[0:2]),
51+
destinationPort: binary.BigEndian.Uint16(raw[2:4]),
52+
sequenceNumber: binary.BigEndian.Uint32(raw[4:8]),
53+
ackNumber: binary.BigEndian.Uint32(raw[8:12]),
54+
rawOffset: offset,
55+
reserved: (raw[12] & 0x0E) >> 1,
56+
flags: binary.BigEndian.Uint16(raw[12:14]) & 0x1FF,
57+
windowSize: binary.BigEndian.Uint16(raw[14:16]),
58+
checksum: binary.BigEndian.Uint16(raw[16:18]),
59+
urgentPointer: binary.BigEndian.Uint16(raw[18:20]),
60+
options: raw[20:hLen],
61+
}, nil
62+
}
63+
64+
func (p TCPPacket) Info() string {
65+
return fmt.Sprintf(`
66+
TCP packet
67+
68+
Source Port: %d
69+
Destination Port: %d
70+
Checksum: %d
71+
72+
===============================
73+
%s
74+
===============================
75+
`,
76+
p.header.sourcePort, p.header.sourcePort, p.header.checksum, p.ipPacket.Info(),
77+
)
78+
}

sockets/raw_socket.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,13 @@ func (rs *RawSocket) ReadPackets() {
120120
continue
121121
}
122122
log.Println(udpPacket.Info())
123-
case "TCP":
123+
case "tcp":
124+
tcpPacket, err := protocols.TCPPacketFromIPPacket(packet)
125+
if err != nil {
126+
log.Println("Error reading TCP packet:", err)
127+
continue
128+
}
129+
log.Println(tcpPacket.Info())
124130
}
125131
}
126132
}

0 commit comments

Comments
 (0)