-
Notifications
You must be signed in to change notification settings - Fork 0
/
net.go
138 lines (121 loc) · 2.46 KB
/
net.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
"bytes"
"encoding/binary"
"fmt"
"log"
"net"
)
const (
FIN = 1 << 0
SYN = 1 << 1
RST = 1 << 2
PSH = 1 << 3
ACK = 1 << 4
URG = 1 << 5
)
type TCPHeader struct {
Source uint16
Destination uint16
SeqNum uint32
AckNum uint32
DataOffset uint8 // 4 bits
Reserved uint8 // 3 bits
ECN uint8 // 3 bits
Ctrl uint8 // 6 bits
Window uint16
Checksum uint16 // Kernel will set this if it's 0
Urgent uint16
Options []TCPOption
}
type TCPOption struct {
Kind uint8
Length uint8
Data []byte
}
// Parse packet into TCPHeader structure
func NewTCPHeader(data []byte) (*TCPHeader, error) {
var tcp TCPHeader
var err error
r := bytes.NewReader(data)
err = binary.Read(r, binary.BigEndian, &tcp.Source)
if err != nil {
return nil, err
}
err = binary.Read(r, binary.BigEndian, &tcp.Destination)
if err != nil {
return nil, err
}
err = binary.Read(r, binary.BigEndian, &tcp.SeqNum)
if err != nil {
return nil, err
}
err = binary.Read(r, binary.BigEndian, &tcp.AckNum)
if err != nil {
return nil, err
}
var mix uint16
binary.Read(r, binary.BigEndian, &mix)
tcp.DataOffset = byte(mix >> 12) // top 4 bits
tcp.Reserved = byte(mix >> 9 & 7) // 3 bits
tcp.ECN = byte(mix >> 6 & 7) // 3 bits
tcp.Ctrl = byte(mix & 0x3f) // bottom 6 bits
err = binary.Read(r, binary.BigEndian, &tcp.Window)
if err != nil {
return nil, err
}
err = binary.Read(r, binary.BigEndian, &tcp.Checksum)
if err != nil {
return nil, err
}
err = binary.Read(r, binary.BigEndian, &tcp.Urgent)
if err != nil {
return nil, err
}
return &tcp, nil
}
func main() {
netaddr, err := net.ResolveIPAddr("ip4", "0.0.0.0")
if err != nil {
log.Println(err)
return
}
conn, err := net.ListenIP("ip4:tcp", netaddr)
if err != nil {
log.Println(err)
return
}
for {
buf := make([]byte, 4096)
n, _, err := conn.ReadFrom(buf)
if err != nil {
fmt.Println(err)
continue
}
tcphdr, err := NewTCPHeader(buf[:n])
if err != nil {
log.Println(err)
continue
}
// No TCP payload
length := n - (int(tcphdr.DataOffset) * 4)
if length <= 0 {
continue
}
// Offset larger than number of bytes read
if int(tcphdr.DataOffset)*4 >= n {
continue
}
data := buf[int(tcphdr.DataOffset)*4 : n]
hs, err := NewHandshake(data)
if err == nil {
fmt.Printf("%v\n", hs)
continue
}
msg, err := NewMessage(data)
if err != nil {
continue
}
fmt.Printf("%v\n", msg)
}
}