tcpdump mailing list archives

Re: Sniffing ranges of ips


From: MMatos <razielukain () gmail com>
Date: Fri, 19 Nov 2004 22:19:37 +0000

Alexander Dupuy wrote:

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.

Yes solving that problem of unsopported non-power-of-two-ranges wouldn't be much difficult

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.


From what you said i think its saffer to dowgrad libpcap to 0.7 because what i really want to do is a program that counts the incoming traffic for a given range of ips. My "would be" app have to deal with a great number of ips so i think non optimized BPF filters are not an option although i've not made benchmarks test to see the impact of the optimization (but by the number of opcodes that both versions produces im getting an ideia :) ) .

Im currently using libpacap version 0.8.3-r1 and i get an output far away from correct for the expression you give
$tcpdump -d 'ip[12:4] >= 0x01020304 and ip[12:4] <= 0x01020506'
(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      #68
(007) ret      #0

And even with the non-optimized i get a diferent output  ( in (024) )
(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      #68
(025) ret      #0


How can I know that a given bpf filter is correct for a given range by analysing its opcodes? Maybe a link to to a doc lying somewhere?

Thanks for the time spent!

MMatos

--
Question.Do you use Linux exclusively, or do you use other operating systems as well?

Alan Cox: I run Linux on pretty much everything except the microwave and washing machine. Those are tempting targets but would probably make Telsa extremely cross.
--  Behind the scenes --
http://www.opensource.org/halloween/

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


Current thread: