-
Notifications
You must be signed in to change notification settings - Fork 9
/
sniffer.go
79 lines (67 loc) · 1.72 KB
/
sniffer.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
package main
import (
"log"
"code.google.com/p/gopacket"
"code.google.com/p/gopacket/layers"
)
type Sniffer interface {
// Open and configure the network interface
Open(config *Config) error
// Close the interface
Close()
// Read the next packet from the interface
ReadPacket() (data []byte, ci gopacket.CaptureInfo, err error)
}
// Layers that we care about decoding
var (
eth layers.Ethernet
ip layers.IPv4
tcp layers.TCP
udp layers.UDP
icmp layers.ICMPv4
dns layers.DNS
payload gopacket.Payload
)
// Listen in an infinite loop for new packets
func Listen(config *Config) error {
// Array to store which layers were decoded
decoded := []gopacket.LayerType{}
// Faster, predefined layer parser that doesn't make copies of the layer slices
parser := gopacket.NewDecodingLayerParser(
layers.LayerTypeEthernet,
ð,
&ip,
&tcp,
&udp,
&icmp,
&dns,
&payload)
// Infinite loop that reads incoming packets
for config.isRunning {
data, ci, err := config.sniffer.ReadPacket()
if err != nil {
log.Printf("Error getting packet: %v %s", err, ci)
continue
}
err = parser.DecodeLayers(data, &decoded)
if err != nil {
log.Printf("Error decoding packet: %v", err)
continue
}
if len(decoded) == 0 {
log.Print("Packet contained no valid layers")
continue
}
// Example of how to get data out of specific layers
// for _, layerType := range decoded {
// switch layerType {
// case layers.LayerTypeIPv4:
// log.Printf("src: %v, dst: %v, proto: %v", ip.SrcIP, ip.DstIP, ip.Protocol)
// }
// }
if config.pcapWriter != nil {
config.pcapWriter.WritePacket(ci, data)
}
}
return nil
}