From ae094f6571ae9c68b1e25b00f91bc44076fa1d90 Mon Sep 17 00:00:00 2001 From: ipchama <25535658+ipchama@users.noreply.github.com> Date: Fri, 6 Mar 2020 21:31:55 -0500 Subject: [PATCH] Feature/dhcpv4 bpf filter (#19) * ebpf filter property added to socketeer and filter added to init. * TODO note. Co-authored-by: ipchama --- cmd/dhcpv4.go | 33 +++++++++++++++++++++++++++++++++ config/socketeer.go | 2 ++ socketeer/socketeer.go | 11 +++++++++++ 3 files changed, 46 insertions(+) diff --git a/cmd/dhcpv4.go b/cmd/dhcpv4.go index 31c2007..120ee21 100644 --- a/cmd/dhcpv4.go +++ b/cmd/dhcpv4.go @@ -10,6 +10,7 @@ import ( "github.com/ipchama/dhammer/socketeer" "github.com/spf13/cobra" "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" "net" "sync" "time" @@ -246,6 +247,37 @@ func init() { options.StatsRate = 5 } + filter := [28]unix.SockFilter{{0x28, 0, 0, 0x0000000c}, // "arp or (port 67 or port 68)" + {0x15, 24, 0, 0x00000806}, + {0x15, 0, 9, 0x000086dd}, + {0x30, 0, 0, 0x00000014}, + {0x15, 2, 0, 0x00000084}, + {0x15, 1, 0, 0x00000006}, + {0x15, 0, 20, 0x00000011}, + {0x28, 0, 0, 0x00000036}, + {0x15, 17, 0, 0x00000043}, + {0x15, 16, 0, 0x00000044}, + {0x28, 0, 0, 0x00000038}, + {0x15, 14, 13, 0x00000043}, + {0x15, 0, 14, 0x00000800}, + {0x30, 0, 0, 0x00000017}, + {0x15, 2, 0, 0x00000084}, + {0x15, 1, 0, 0x00000006}, + {0x15, 0, 10, 0x00000011}, + {0x28, 0, 0, 0x00000014}, + {0x45, 8, 0, 0x00001fff}, + {0xb1, 0, 0, 0x0000000e}, + {0x48, 0, 0, 0x0000000e}, + {0x15, 4, 0, 0x00000043}, + {0x15, 3, 0, 0x00000044}, + {0x48, 0, 0, 0x00000010}, + {0x15, 1, 0, 0x00000043}, + {0x15, 0, 1, 0x00000044}, + {0x6, 0, 0, 0x00040000}, + {0x6, 0, 0, 0x00000000}} + + socketeerOptions.EbpfFilter = &unix.SockFprog{28, &filter[0]} + gHammer = hammer.New(socketeerOptions, options) err = gHammer.Init(ApiAddress, ApiPort) @@ -253,6 +285,7 @@ func init() { if err != nil { panic(err) } + err = gHammer.Run() if err != nil { diff --git a/config/socketeer.go b/config/socketeer.go index 9423761..0aad89a 100644 --- a/config/socketeer.go +++ b/config/socketeer.go @@ -1,6 +1,7 @@ package config import ( + "golang.org/x/sys/unix" "net" ) @@ -8,4 +9,5 @@ type SocketeerOptions struct { InterfaceName string GatewayMAC net.HardwareAddr PromiscuousMode bool + EbpfFilter *unix.SockFprog } diff --git a/socketeer/socketeer.go b/socketeer/socketeer.go index 4fc1c6a..d8fa472 100644 --- a/socketeer/socketeer.go +++ b/socketeer/socketeer.go @@ -6,11 +6,15 @@ import ( "github.com/google/gopacket/layers" "github.com/ipchama/dhammer/config" "github.com/ipchama/dhammer/message" + "golang.org/x/sys/unix" "net" "runtime" "syscall" ) +// TODO: Move syscalls from syscall package to golang.org/x/sys/unix. +// Maybe add custom port to ebpf rules. + type RawSocketeer struct { socketFd int IfInfo *net.Interface @@ -57,6 +61,13 @@ func (s *RawSocketeer) Init() error { return err } + if s.options.EbpfFilter != nil { + err = unix.SetsockoptSockFprog(s.socketFd, syscall.SOL_SOCKET, syscall.SO_ATTACH_FILTER, s.options.EbpfFilter) + if err != nil { + return err + } + } + s.IfInfo, err = net.InterfaceByName(s.options.InterfaceName) if err != nil {