/
index.go
105 lines (89 loc) · 2.42 KB
/
index.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
package parseTCP
import (
"errors"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"log"
"gopkg.in/oleiade/reflections.v1"
"strings"
"math"
"encoding/hex"
"bytes"
"os"
"fmt"
)
var infolog = log.New(os.Stdout,
"", 0)
type Packet struct {
Gopacket gopacket.Packet
IP *layers.IPv4
TCP *layers.TCP
Recompile func() ([]byte, error)
Print func(...int)
}
func ParseTCPPacket(packetData []byte) (packet Packet, err error) {
packet.Gopacket = gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.Default)
ipLayer := packet.Gopacket.Layer(layers.LayerTypeIPv4)
if ipLayer == nil {
err = errors.New("No IP layer!")
infolog.Println(hex.Dump(packetData))
return
}
packet.IP = ipLayer.(*layers.IPv4)
ip := packet.IP
tcpLayer := packet.Gopacket.Layer(layers.LayerTypeTCP)
if tcpLayer == nil {
err = errors.New("No TCP layer!")
return
}
packet.TCP = tcpLayer.(*layers.TCP)
tcp := packet.TCP
packet.Recompile = func() ([]byte, error) {
options := gopacket.SerializeOptions{
ComputeChecksums: true,
FixLengths: true,
}
newBuffer := gopacket.NewSerializeBuffer()
tcp.SetNetworkLayerForChecksum(ip)
err := gopacket.SerializePacket(newBuffer, options, packet.Gopacket)
if err != nil {
return nil, err
}
return newBuffer.Bytes(), nil
}
toChar := func(b byte) rune {
if b < 32 || b > 126 {
return rune('.')
}
return rune(b)
}
toString := func(data []byte) string {
var buffer bytes.Buffer
for _, d := range data {
buffer.WriteRune(toChar(d))
}
return buffer.String()
}
packet.Print = func(payloadLimits ...int) {
result := fmt.Sprintf("Packet from %s:%d to %s:%d seq=%d ack=%d", ip.SrcIP.String(), tcp.SrcPort, ip.DstIP.String(), tcp.DstPort, tcp.Seq, tcp.Ack)
flags := strings.Split("FIN SYN RST PSH ACK URG ECE CWR NS", " ")
for _, flag := range flags {
val, err := reflections.GetField(tcp, flag)
if err != nil {
infolog.Println(err, "REFLECT ERROR!")
}
if val.(bool) {
result += fmt.Sprintf(" %s", flag)
}
}
infolog.Println(result)
payloadLimit := 100
if len(payloadLimits) > 0 {
payloadLimit = payloadLimits[0]
}
if len(tcp.Payload) != 0 {
infolog.Println("TCP PAYLOAD:", toString(tcp.Payload[:int(math.Min(float64(len(tcp.Payload)), float64(payloadLimit)))]))
}
}
return
}