-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
92 lines (73 loc) · 1.91 KB
/
main.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
package main
import (
"bytes"
"flag"
"log"
"net"
"syscall"
"github.com/PreetamJinka/sflow"
"github.com/PreetamJinka/udpchan"
)
// host order (usually little endian) -> network order (big endian)
func htons(n int) int {
return int(int16(byte(n))<<8 | int16(byte(n>>8)))
}
func main() {
sampleEvery := flag.Int("sample-every", 256, "sample every N packets")
sampleSize := flag.Int("sample-size", 256, "sample size in bytes")
collectorAddress := flag.String("collector-address", ":6343", "address of collector")
sourceIP := flag.String("source-ip", "127.0.0.1", "IP address of this host")
flag.Parse()
log.Println("Starting sampler")
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, htons(syscall.ETH_P_ALL))
if err != nil {
log.Fatal(err)
}
log.Println("Opened a raw socket")
collector, err := udpchan.Connect(*collectorAddress)
if err != nil {
log.Fatal(err)
}
log.Println("Ready to send to collector at", *collectorAddress)
enc := sflow.NewEncoder(net.ParseIP(*sourceIP), 1, 1)
i := 0
sequenceNum := 0
buf := make([]byte, 65535)
outboundBuf := &bytes.Buffer{}
for {
i++
n, _, err := syscall.Recvfrom(fd, buf, 0)
if err != nil {
log.Fatal(err)
}
if i%*sampleEvery != 0 {
continue
}
numStripped := 0
if n > *sampleSize {
numStripped = n - *sampleSize
}
flowSample := &sflow.FlowSample{
SequenceNum: uint32(sequenceNum),
SamplingRate: uint32(*sampleEvery),
Records: []sflow.Record{
sflow.RawPacketFlow{
Protocol: 1, // 1 = Ethernet
FrameLength: uint32(n),
Stripped: uint32(numStripped),
HeaderSize: uint32(n - numStripped),
Header: buf[:n-numStripped],
},
},
}
err = enc.Encode(outboundBuf, []sflow.Sample{flowSample})
if err != nil {
log.Fatal(err)
}
collector <- outboundBuf.Bytes()
log.Println("Sent a sample")
sequenceNum++
outboundBuf.Reset()
}
log.Println("sampler exiting")
}