9
9
"net"
10
10
"os"
11
11
"runtime"
12
+ "strings"
12
13
"sync"
13
14
"syscall"
14
15
"time"
@@ -170,21 +171,31 @@ func (l *Listener) ListenBackground(ctx context.Context, handler PacketHandler)
170
171
func (l * Listener ) Filter (ifi net.Interface ) (filter string ) {
171
172
// https://www.tcpdump.org/manpages/pcap-filter.7.html
172
173
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 )
176
177
}
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 )
180
185
}
181
186
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 )
184
197
}
185
- filter = fmt .Sprintf ("(host %s and (%s))" , l .host , filter )
186
198
187
- log .Println ("BPF filter: " + filter )
188
199
return
189
200
}
190
201
@@ -259,13 +270,7 @@ func (l *Listener) PcapHandle(ifi net.Interface) (handle *pcap.Handle, err error
259
270
if err != nil {
260
271
return nil , fmt .Errorf ("PCAP Activate device error: %q, interface: %q" , err , ifi .Name )
261
272
}
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 )
269
274
fmt .Println ("Interface:" , ifi .Name , ". BPF Filter:" , l .BPFFilter )
270
275
err = handle .SetBPFFilter (l .BPFFilter )
271
276
if err != nil {
@@ -284,13 +289,7 @@ func (l *Listener) SocketHandle(ifi net.Interface) (handle Socket, err error) {
284
289
if err = handle .SetPromiscuous (l .Promiscuous || l .Monitor ); err != nil {
285
290
return nil , fmt .Errorf ("promiscuous mode error: %q, interface: %q" , err , ifi .Name )
286
291
}
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 )
294
293
fmt .Println ("BPF Filter: " , l .BPFFilter )
295
294
if err = handle .SetBPFFilter (l .BPFFilter ); err != nil {
296
295
handle .Close ()
@@ -416,16 +415,12 @@ func (l *Listener) activatePcapFile() (err error) {
416
415
if handle , e = pcap .OpenOffline (l .host ); e != nil {
417
416
return fmt .Errorf ("open pcap file error: %q" , e )
418
417
}
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
+
429
424
if e = handle .SetBPFFilter (l .BPFFilter ); e != nil {
430
425
handle .Close ()
431
426
return fmt .Errorf ("BPF filter error: %q, filter: %s" , e , l .BPFFilter )
@@ -481,6 +476,18 @@ func isDevice(addr string, ifi net.Interface) bool {
481
476
return addr == ifi .Name || addr == fmt .Sprintf ("%d" , ifi .Index ) || (addr != "" && addr == ifi .HardwareAddr .String ())
482
477
}
483
478
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
+
484
491
func listenAll (addr string ) bool {
485
492
switch addr {
486
493
case "" , "0.0.0.0" , "[::]" , "::" :
@@ -489,6 +496,23 @@ func listenAll(addr string) bool {
489
496
return false
490
497
}
491
498
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
+
492
516
func pcapLinkTypeLength (lType int ) (int , bool ) {
493
517
switch layers .LinkType (lType ) {
494
518
case layers .LinkTypeEthernet :
0 commit comments