/
analyze.go
143 lines (125 loc) · 3.54 KB
/
analyze.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
139
140
141
142
143
package analyze
import (
"fmt"
"log"
"runtime"
"sync"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func view(p packetInfo) {
fmt.Println(p.String())
}
func getPacketSourceFromPcap(pcapFile *string) (*gopacket.PacketSource, func(), error) {
handle, err := pcap.OpenOffline(*pcapFile)
if err != nil {
return nil, nil, err
}
return gopacket.NewPacketSource(handle, layers.LinkTypeEthernet), handle.Close, nil
}
func getPacketSourceFromIF(ifname *string) (*gopacket.PacketSource, func(), error) {
handle, err := pcap.OpenLive(*ifname, 1600, true, pcap.BlockForever)
if err != nil {
return nil, nil, err
}
return gopacket.NewPacketSource(handle, handle.LinkType()), handle.Close, nil
}
func ReadPcap(pcapFile *string, samplingRate *int) {
packetSource, handleclose, err := getPacketSourceFromPcap(pcapFile)
if err != nil {
log.Fatal(err)
}
defer handleclose()
analyzePacketSource(packetSource, samplingRate)
}
func ReadIF(ifname *string, samplingRate *int) {
packetSource, handleclose, err := getPacketSourceFromIF(ifname)
if err != nil {
log.Fatal(err)
}
defer handleclose()
analyzePacketSource(packetSource, samplingRate)
}
func analyzePacketSource(packetSource *gopacket.PacketSource, samplingRate *int) {
cpus := runtime.NumCPU()
ch := make(chan packetInfo, cpus)
wg := &sync.WaitGroup{}
sampleCounter := *samplingRate
go func() {
for true {
view(<-ch)
wg.Done()
}
}()
for packet := range packetSource.Packets() {
if sampleCounter == *samplingRate {
wg.Add(1)
go analyze(&packet, &ch)
sampleCounter = 1
} else {
sampleCounter++
}
}
wg.Wait()
}
func analyze(p *gopacket.Packet, ch *chan packetInfo) {
var pInfo packetInfo
pInfo.Time = (*p).Metadata().Timestamp.String()
pInfo.Epochtime = (*p).Metadata().Timestamp.Unix()
pInfo.Length = (*p).Metadata().Length
pInfo.SrcMac = (*p).LinkLayer().LinkFlow().Src().String()
pInfo.DstMac = (*p).LinkLayer().LinkFlow().Dst().String()
for _, layer := range (*p).Layers() {
switch layer.LayerType() {
case layers.LayerTypeIPv4:
ip, _ := layer.(*layers.IPv4)
if pInfo.SrcIP == "" {
pInfo.SrcIP = ip.SrcIP.String()
pInfo.DstIP = ip.DstIP.String()
pInfo.Proto = ip.Protocol.String()
}
case layers.LayerTypeIPv6:
ip, _ := layer.(*layers.IPv6)
pInfo.Proto = ip.LayerType().String()
if pInfo.SrcIP == "" {
pInfo.SrcIP = ip.SrcIP.String()
pInfo.DstIP = ip.DstIP.String()
}
case layers.LayerTypeICMPv4:
icmpv4 := layer.(*layers.ICMPv4)
pInfo.Proto = layer.LayerType().String()
pInfo.IcmpCode = int(icmpv4.TypeCode.Code())
pInfo.IcmpType = int(icmpv4.TypeCode.Type())
case layers.LayerTypeICMPv6:
icmpv4 := layer.(*layers.ICMPv6)
pInfo.Proto = layer.LayerType().String()
pInfo.IcmpCode = int(icmpv4.TypeCode.Code())
pInfo.IcmpType = int(icmpv4.TypeCode.Type())
case layers.LayerTypeTCP:
tcp, _ := layer.(*layers.TCP)
pInfo.SrcPort = int(tcp.SrcPort)
pInfo.DstPort = int(tcp.DstPort)
pInfo.Seq = tcp.Seq
pInfo.TCPFlags.FIN = tcp.FIN
pInfo.TCPFlags.SYN = tcp.SYN
pInfo.TCPFlags.RST = tcp.RST
pInfo.TCPFlags.PSH = tcp.PSH
pInfo.TCPFlags.ACK = tcp.ACK
pInfo.TCPFlags.URG = tcp.URG
pInfo.TCPFlags.ECE = tcp.ECE
pInfo.TCPFlags.CWR = tcp.CWR
pInfo.TCPFlags.NS = tcp.NS
pInfo.TCPFlags.calcBit()
case layers.LayerTypeUDP:
udp, _ := layer.(*layers.UDP)
pInfo.SrcPort = int(udp.SrcPort)
pInfo.DstPort = int(udp.DstPort)
default:
if pInfo.Proto == "" {
pInfo.Proto = layer.LayerType().String()
}
}
}
*ch <- pInfo
}