-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
116 lines (98 loc) · 2.74 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
// from https://d0u9.io/use-cilium-ebpf-to-compile-and-load-tc-bpf-code/
import (
"log"
"os"
"os/signal"
"strconv"
"time"
"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
)
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go tc bpf/bpf.c -- -I./bpf
func InttoIP4(ipInt uint32) string {
// need to do two bit shifting and “0xff” masking
b0 := strconv.FormatInt(int64((ipInt>>24)&0xff), 10)
b1 := strconv.FormatInt(int64((ipInt>>16)&0xff), 10)
b2 := strconv.FormatInt(int64((ipInt>>8)&0xff), 10)
b3 := strconv.FormatInt(int64((ipInt & 0xff)), 10)
return b0 + "." + b1 + "." + b2 + "." + b3
}
const INTERFACE = "enp1s0"
func main() {
var err error
// Load bpf programs and maps into the kernel
objs := tcObjects{}
if err := loadTcObjects(&objs, nil); err != nil {
log.Fatalf("loading objects: %v", err)
}
defer objs.Close()
progFd := objs.TcMain.FD()
intf, err := netlink.LinkByName(INTERFACE)
if err != nil {
log.Fatalf("cannot find %s: %v", INTERFACE, err)
}
attrs := netlink.QdiscAttrs{
LinkIndex: intf.Attrs().Index, //Interface index
Handle: netlink.MakeHandle(0xffff, 0),
Parent: netlink.HANDLE_CLSACT,
}
// declare the qdisc
qdisc := &netlink.GenericQdisc{
QdiscAttrs: attrs,
QdiscType: "clsact",
}
// add the qdisc
if err := netlink.QdiscAdd(qdisc); err != nil {
log.Fatalf("cannot add clsact qdisc: %v", err)
}
//filter attributes
filterAttrs := netlink.FilterAttrs{
LinkIndex: intf.Attrs().Index,
// Parent: netlink.HANDLE_MIN_INGRESS, //direction
Parent: netlink.HANDLE_MIN_EGRESS,
Handle: netlink.MakeHandle(0, 1),
Protocol: unix.ETH_P_ALL,
Priority: 1,
}
//declare the BPF filter
filter := &netlink.BpfFilter{
FilterAttrs: filterAttrs,
Fd: progFd,
Name: "hi-tc",
DirectAction: true,
}
//add the filter
if err := netlink.FilterAdd(filter); err != nil {
log.Fatalf("cannot attach bpf object to filter: %v", err)
}
log.Printf("Counting packets on %s...", INTERFACE)
//repeatedly output the map contents
tick := time.Tick(time.Second)
stop := make(chan os.Signal, 5)
signal.Notify(stop, os.Interrupt)
pktCount := objs.PktCount
for {
select {
case <-tick:
log.Printf("==========")
var (
entries = pktCount.Iterate()
packetdets tcPacketdets
count uint64
)
for entries.Next(&packetdets, &count) {
source := InttoIP4(packetdets.Source)
source_port := packetdets.SourcePort
dest := InttoIP4(packetdets.Dest)
dest_port := packetdets.DestPort
ip_protocol := packetdets.IpProtocol
log.Printf("%s[%d] -> %s[%d] proto %d: %d", source, source_port, dest, dest_port, ip_protocol, count)
}
log.Printf("")
case <-stop:
log.Printf("Received signal stopping.")
return
}
}
}