tcpdump mailing list archives

Re: Sniffing ranges of ips


From: Alexander Dupuy <dupuy () sysd com>
Date: Fri, 19 Nov 2004 15:52:51 -0500

Jefferson Ogata wrote:
Or you can do something more utilitarian, such as:

tcpdump [options] '( ip[12:4] >= 0xc0a8020f ) and ( ip[12:4] <= 0xc0a80228 )'

For some reason (subscription e-mail vs. sending e-mail) my previous messages on this topic seem not to have gone out to the list, so I'll re-summarize in the light of Jefferson Ogata's useful suggestions. I came up with pretty much the same range hack, but also noticed that libpcap 0.8.3 has an optimizer bug that breaks that expression.

With IPv4 or IPv6, if the range falls on a power-of-two boundary, you can use "src net 192.168.1.16/28"; this is CIDR notation, and doesn't mean addresses .16 to .28 (or .40, as MMatos wrote), but rather the 28-bit netmask 0xfffffff0 for 192.168.1.16 to .31. This functionality may not be present in all versions of tcpdump; it exists in version 3.7.1 and later, and may be present in some earlier ones as well.

This doesn't support non-power-of-two ranges; for example addresses between 192.168.1.10 and 192.168.1.19. For something like that, with IPv4 you can use a hack like "(ip[12:4] >= 0x01020304) and (ip[12:4] <= 0x01020506)" to express that the source IP address should be within the range of 1.2.3.4 to 1.2.5.6 (inclusive). No simple expression exists for non-power-of-two IPv6 address ranges, but you could probably cobble up something only fairly heinous by computing enclosing power-of-two ranges using an adaptation of Jefferson Ogata's genrange.pl and aggregate.pl scripts and doing something similar with comparisons on low-order four-byte pieces of the address.

Note also that there is a bug in the libpcap BPF optimizer (as of 0.8.3) that
breaks the hack described above, so you may have to use the -O (capital letter
O) tcpdump option to disable the optimizer.

The opcodes emitted by libpcap 0.8.3 "tcpdump -d 'ip[12:4] >= 0x01020304 and ip[12:4} <= 0x01020506" are:
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 7
(002) ld       [26]
(003) ldx      #0x1020304
(004) jge      x                jt 5    jf 7
(005) jgt      x                jt 7    jf 6
(006) ret      #96
(007) ret      #0

but to properly compute the address range, they should actually be more like:
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 7
(002) ld       [26]
(003) ldx      #0x1020304
(004) jge      x                jt 5    jf 8
(005) ldx      #0x1020506
(006) jgt      x                jt 8    jf 7
(007) ret      #96
(008) ret      #0

with tcpdump -O to disable optimization, what you get (correct, but much
slower) is:
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 25
(002) ld       #0xc
(003) st       M[0]
(004) ldx      M[0]
(005) ld       [x + 14]
(006) st       M[1]
(007) ld       #0x1020304
(008) st       M[2]
(009) ldx      M[2]
(010) ld       M[1]
(011) jge      x                jt 12   jf 25
(012) ldh      [12]
(013) jeq      #0x800           jt 14   jf 25
(014) ld       #0xc
(015) st       M[2]
(016) ldx      M[2]
(017) ld       [x + 14]
(018) st       M[3]
(019) ld       #0x1020506
(020) st       M[4]
(021) ldx      M[4]
(022) ld       M[3]
(023) jgt      x                jt 25   jf 24
(024) ret      #96
(025) ret      #0

However, the libpcap 0.7 optimizer not only generates correct BPF, but it is shorter than any of the above, entirely eliminating the use of the index register:
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 6
(002) ld       [26]
(003) jge      #0x1020304       jt 4    jf 6
(004) jgt      #0x1020506       jt 6    jf 5
(005) ret      #96
(006) ret      #0

@alex
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.


Current thread: