Skip to content

Commit 763ad9b

Browse files
committed
Merge branch 'DimaGolomozy-more-exact-bpf-filter'
2 parents 7e173b0 + b1972fb commit 763ad9b

File tree

2 files changed

+65
-36
lines changed

2 files changed

+65
-36
lines changed

capture/capture.go

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net"
1010
"os"
1111
"runtime"
12+
"strings"
1213
"sync"
1314
"syscall"
1415
"time"
@@ -170,21 +171,31 @@ func (l *Listener) ListenBackground(ctx context.Context, handler PacketHandler)
170171
func (l *Listener) Filter(ifi net.Interface) (filter string) {
171172
// https://www.tcpdump.org/manpages/pcap-filter.7.html
172173

173-
port := fmt.Sprintf("portrange 0-%d", 1<<16-1)
174-
if l.port != 0 {
175-
port = fmt.Sprintf("port %d", l.port)
174+
hosts := []string{l.host}
175+
if listenAll(l.host) || isDevice(l.host, ifi) {
176+
hosts = interfaceAddresses(ifi)
176177
}
177-
filter = fmt.Sprintf("%s dst %s", l.Transport, port)
178-
if l.trackResponse {
179-
filter = fmt.Sprintf("%s %s", l.Transport, port)
178+
179+
filter = portsFilter(l.Transport, "dst", l.port)
180+
181+
if len(hosts) != 0 {
182+
filter = fmt.Sprintf("((%s) and (%s))", filter, hostsFilter("dst", hosts))
183+
} else {
184+
filter = fmt.Sprintf("(%s)", filter)
180185
}
181186

182-
if listenAll(l.host) || isDevice(l.host, ifi) {
183-
return "(" + filter + ")"
187+
if l.trackResponse {
188+
responseFilter := portsFilter(l.Transport, "src", l.port)
189+
190+
if len(hosts) != 0 {
191+
responseFilter = fmt.Sprintf("((%s) and (%s))", responseFilter, hostsFilter("src", hosts))
192+
} else {
193+
responseFilter = fmt.Sprintf("(%s)", responseFilter)
194+
}
195+
196+
filter = fmt.Sprintf("%s or %s", filter, responseFilter)
184197
}
185-
filter = fmt.Sprintf("(host %s and (%s))", l.host, filter)
186198

187-
log.Println("BPF filter: " + filter)
188199
return
189200
}
190201

@@ -259,13 +270,7 @@ func (l *Listener) PcapHandle(ifi net.Interface) (handle *pcap.Handle, err error
259270
if err != nil {
260271
return nil, fmt.Errorf("PCAP Activate device error: %q, interface: %q", err, ifi.Name)
261272
}
262-
if l.BPFFilter != "" {
263-
if l.BPFFilter[0] != '(' || l.BPFFilter[len(l.BPFFilter)-1] != ')' {
264-
l.BPFFilter = "(" + l.BPFFilter + ")"
265-
}
266-
} else {
267-
l.BPFFilter = l.Filter(ifi)
268-
}
273+
l.BPFFilter = l.Filter(ifi)
269274
fmt.Println("Interface:", ifi.Name, ". BPF Filter:", l.BPFFilter)
270275
err = handle.SetBPFFilter(l.BPFFilter)
271276
if err != nil {
@@ -284,13 +289,7 @@ func (l *Listener) SocketHandle(ifi net.Interface) (handle Socket, err error) {
284289
if err = handle.SetPromiscuous(l.Promiscuous || l.Monitor); err != nil {
285290
return nil, fmt.Errorf("promiscuous mode error: %q, interface: %q", err, ifi.Name)
286291
}
287-
if l.BPFFilter != "" {
288-
if l.BPFFilter[0] != '(' || l.BPFFilter[len(l.BPFFilter)-1] != ')' {
289-
l.BPFFilter = "(" + l.BPFFilter + ")"
290-
}
291-
} else {
292-
l.BPFFilter = l.Filter(ifi)
293-
}
292+
l.BPFFilter = l.Filter(ifi)
294293
fmt.Println("BPF Filter: ", l.BPFFilter)
295294
if err = handle.SetBPFFilter(l.BPFFilter); err != nil {
296295
handle.Close()
@@ -416,16 +415,12 @@ func (l *Listener) activatePcapFile() (err error) {
416415
if handle, e = pcap.OpenOffline(l.host); e != nil {
417416
return fmt.Errorf("open pcap file error: %q", e)
418417
}
419-
if l.BPFFilter != "" {
420-
if l.BPFFilter[0] != '(' || l.BPFFilter[len(l.BPFFilter)-1] != ')' {
421-
l.BPFFilter = "(" + l.BPFFilter + ")"
422-
}
423-
} else {
424-
addr := l.host
425-
l.host = ""
426-
l.BPFFilter = l.Filter(net.Interface{})
427-
l.host = addr
428-
}
418+
419+
tmp := l.host
420+
l.host = ""
421+
l.BPFFilter = l.Filter(net.Interface{})
422+
l.host = tmp
423+
429424
if e = handle.SetBPFFilter(l.BPFFilter); e != nil {
430425
handle.Close()
431426
return fmt.Errorf("BPF filter error: %q, filter: %s", e, l.BPFFilter)
@@ -481,6 +476,18 @@ func isDevice(addr string, ifi net.Interface) bool {
481476
return addr == ifi.Name || addr == fmt.Sprintf("%d", ifi.Index) || (addr != "" && addr == ifi.HardwareAddr.String())
482477
}
483478

479+
func interfaceAddresses(ifi net.Interface) []string {
480+
var hosts []string
481+
if addrs, err := ifi.Addrs(); err == nil {
482+
for _, addr := range addrs {
483+
if ip := addr.(*net.IPNet).IP.To16(); ip != nil {
484+
hosts = append(hosts, ip.String())
485+
}
486+
}
487+
}
488+
return hosts
489+
}
490+
484491
func listenAll(addr string) bool {
485492
switch addr {
486493
case "", "0.0.0.0", "[::]", "::":
@@ -489,6 +496,23 @@ func listenAll(addr string) bool {
489496
return false
490497
}
491498

499+
func portsFilter(transport string, direction string, port uint16) string {
500+
if port == 0 {
501+
return fmt.Sprintf("%s %s portrange 0-%d", transport, direction, 1<<16-1)
502+
}
503+
504+
return fmt.Sprintf("%s %s port %d", transport, direction, port)
505+
}
506+
507+
func hostsFilter(direction string, hosts []string) string {
508+
var hostsFilters []string
509+
for _, host := range hosts {
510+
hostsFilters = append(hostsFilters, fmt.Sprintf("%s host %s", direction, host))
511+
}
512+
513+
return strings.Join(hostsFilters, " or ")
514+
}
515+
492516
func pcapLinkTypeLength(lType int) (int, bool) {
493517
switch layers.LinkType(lType) {
494518
case layers.LinkTypeEthernet:

gor.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@ var (
2222
memprofile = flag.String("memprofile", "", "write memory profile to this file")
2323
)
2424

25-
func loggingMiddleware(next http.Handler) http.Handler {
25+
func loggingMiddleware(addr string, next http.Handler) http.Handler {
2626
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27+
if r.URL.Path == "/loop" {
28+
_, err := http.Get("http://" + addr)
29+
log.Println(err)
30+
}
31+
2732
rb, _ := httputil.DumpRequest(r, false)
2833
log.Println(string(rb))
2934
next.ServeHTTP(w, r)
@@ -45,7 +50,7 @@ func main() {
4550

4651
Debug(0, "Started example file server for current directory on address ", args[1])
4752

48-
log.Fatal(http.ListenAndServe(args[1], loggingMiddleware(http.FileServer(http.Dir(dir)))))
53+
log.Fatal(http.ListenAndServe(args[1], loggingMiddleware(args[1], http.FileServer(http.Dir(dir)))))
4954
} else {
5055
flag.Parse()
5156
checkSettings()

0 commit comments

Comments
 (0)