Ask Your Question
1

Capture filter pppoes does not work as expected

asked 2021-10-27 05:32:01 +0000

ripper gravatar image

updated 2021-10-27 22:35:11 +0000

cmaynard gravatar image

Dear I try to capture packet from customer which has byte end by 1. my capture has two part : packet send and recevied. The first part like this :

( ether dst 00:00:00:00:00:01 and pppoes and ip[19:1]&0x0f=0x01 )

This capture filter works well The second part

( ether src 00:00:00:00:00:01 and pppoes and ip[15:1]&0x0f=0x01 )

This capture filter works well also But when combine two of them : the filter bar is red ( seems that wrong syntax filter )

( ether dst 00:00:00:00:00:01 and pppoes and ip[19:1]&0x0f=0x01 ) or ( ether src 00:00:00:00:00:01 and pppoes and ip[15:1]&0x0f=0x01 )

Please help me to fix the capture filter syntax Thank so much

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2021-10-27 18:26:40 +0000

cmaynard gravatar image

updated 2021-10-28 01:19:43 +0000

What's needed is support for pppoes src and pppoes dst or some other work around.

The work-around (and as far as I'm aware the only way to handle this) is to avoid using pppoes, at least in the first expression. What we need to be able to do is to construct the equivalent BPF without using pppoes. First, what does the BPF look like if we do use pppoes? Well, it looks like this:

dumpcap.exe -d -f "ether dst 00:00:00:00:00:01 and pppoes and ip[19:1]&0x0f=0x01"
(000) ld       [2]
(001) jeq      #0x1             jt 2    jf 12
(002) ldh      [0]
(003) jeq      #0x0             jt 4    jf 12
(004) ldh      [12]
(005) jeq      #0x8864          jt 6    jf 12
(006) ldh      [20]
(007) jeq      #0x21            jt 8    jf 12
(008) ldb      [41]
(009) and      #0xf
(010) jeq      #0x1             jt 11   jf 12
(011) ret      #262144
(012) ret      #0

What is this doing?

  • First, it's checking that the Ethernet destination address is 00:00:00:00:00:01. It's doing this in 2 parts: (1) the last 4 bytes is 00:00:00:01 and (2) the first 2 bytes are 00:00. These are instructions 000-003.
  • Second, it's checking that the Ethertype is 0x8864, which is the IANA-assigned Ethertype for "PPP over Ethernet (PPPoE) Session Stage". These are instructions 004-005.
  • Third, it's checking that the PPP Protocol ID is IPv4. These are instructions 006-007.
  • Fourth, it's checking that the lower nibble of the last octet of the destination IP address is 1. These are instructions 008-010.

(The breakdown of the other expression is quite similar, except for the changes to the offsets for comparing the Ethernet source address and the lower nibble of the last octet of the IPv4 source address. That breakdown and analysis is left as an exercise for the reader.)

To reproduce this same BPF without using the pppoes keyword then, we simply need to manually specify all the offsets. Here is such a filter that accomplishes that, with BFP included for comparison:

dumpcap.exe -d -f "ether dst 00:00:00:00:00:01 and ether[12:2] = 0x8864 and ether[20:2] = 0x0021 and ether[41:1] & 0x0f = 0x01"
(000) ld       [2]
(001) jeq      #0x1             jt 2    jf 12
(002) ldh      [0]
(003) jeq      #0x0             jt 4    jf 12
(004) ldh      [12]
(005) jeq      #0x8864          jt 6    jf 12
(006) ldh      [20]
(007) jeq      #0x21            jt 8    jf 12
(008) ldb      [41]
(009) and      #0xf
(010) jeq      #0x1             jt 11   jf 12
(011) ret      #262144
(012) ret      #0

Now all that's needed is to or the two expressions together. This can be done in 1 of 2 ways, the first being a bit easier because now we can use the pppoes keyword:

dumpcap.exe -d -f "(ether dst 00:00:00:00:00:01 and ether[12:2] = 0x8864 and ether[20:2] = 0x0021 and ether[41:1] & 0x0f = 0x01 ...
(more)
edit flag offensive delete link more

Comments

Not sure I'd like to maintain it but looks good! :-)

Chuckc gravatar imageChuckc ( 2021-10-27 19:58:50 +0000 )edit

Well, you'll notice that there are duplicate checks for Ethertype 0x8864 as well as for the PPP Protocol ID being 0x0021, so it can be optimized a bit. For example:

dumpcap.exe -d -f "ether[12:2] = 0x8864 and ether[20:2] = 0x0021 and ((ether dst 00:00:00:00:00:01 and ether[41:1] & 0x0f = 0x01) or (ether src 00:00:00:00:00:01 and ether[37:1] & 0x0f = 0x01))"
(000) ldh      [12]
(001) jeq      #0x8864          jt 2    jf 19
(002) ldh      [20]
(003) jeq      #0x21            jt 4    jf 19
(004) ld       [2]
(005) jeq      #0x1             jt 6    jf 11
(006) ldh      [0]
(007) jeq      #0x0             jt 8    jf 11
(008) ldb      [41]
(009) and      #0xf
(010) jeq      #0x1             jt 18   jf 11
(011) ld       [8]
(012) jeq      #0x1             jt 13   jf 19
(013) ldh      [6]
(014) jeq      #0x0             jt 15   jf 19
(015 ...
(more)
cmaynard gravatar imagecmaynard ( 2021-10-27 22:00:48 +0000 )edit

I'm surprised that no one (that I could find with a little Googling) has ever asked for #defines and/or macros in pcap-filter or the Wireshark capture filters. It's all going to get compiled to byte code but sure would help readability when using byte offsets (slices).

Chuckc gravatar imageChuckc ( 2021-10-28 00:30:20 +0000 )edit

Interesting idea. Something like this maybe?

    Filter Name             Filter Expression
    -----------             -----------------
    PPPOES                  ether[12:2] = 0x8864
    PPP-ProtocolID-Is-IP    ether[20:2] = 0x0021
    ASK-24957               ${PPPOES} and ${PPP-ProtocolID-Is-IP} and ...

Maybe open a Wireshark Enhancement Issue for this?

cmaynard gravatar imagecmaynard ( 2021-10-28 01:13:54 +0000 )edit

Dear First of all, thanks all for your help.

@cmaynard : thank you so much for your wonderful explain. i have gain useful knowledge after reading your post

ripper gravatar imageripper ( 2021-10-28 01:15:27 +0000 )edit
0

answered 2021-10-27 14:51:50 +0000

Chuckc gravatar image

updated 2021-10-27 14:55:02 +0000

This is worthy of an issue on the libpcap Github issues.

After the first pppoes, the packet is no longer considered to be Ethernet (type 0x0800) so the second ether is not valid. What's needed is support for pppoes src and pppoes dst or some other work around.

To look at inside of a capture filter, use dumpcap -d to dump the byte code for the filter:

~$ dumpcap.exe -i 5 -d -f "( ether dst 00:00:00:00:00:01 and pppoes and ip[19:1]&0x0f=0x01 )"
Capturing on 'Ethernet'
(000) ld       [2]
(001) jeq      #0x1             jt 2    jf 12
(002) ldh      [0]
(003) jeq      #0x0             jt 4    jf 12
(004) ldh      [12]
(005) jeq      #0x8864          jt 6    jf 12
(006) ldh      [20]
(007) jeq      #0x21            jt 8    jf 12
(008) ldb      [41]
(009) and      #0xf
(010) jeq      #0x1             jt 11   jf 12
(011) ret      #262144
(012) ret      #0

The check of [12] for #0x8864 is looking for pppoes in the Ethernet Type bytes.

After the pppoes it is no longer considered Ethernet 0x0800 so the second ether src fails.

~$ dumpcap.exe -i 5 -d -f "(( ether dst 00:00:00:00:00:01 and pppoes and ip[19:1]&0x0f=0x01 ) or (ether src 00:00:00:00:00:01))"
Capturing on 'Ethernet'
dumpcap: Invalid capture filter "(( ether dst 00:00:00:00:00:01 and pppoes and ip[19:1]&0x0f=0x01
 ) or (ether src 00:00:00:00:00:01))" for interface '\Device\NPF_xxx'.

That string isn't a valid capture filter (ethernet addresses supported only on ethernet/FDDI/toke
n ring/802.11/ATM LANE/Fibre Channel).
See the User's Guide for a description of the capture filter syntax.

If libpcap supported frame protocol to look at byte level then a lower level filter for the src and dst addresses could be created but it doesn't so you can't.
(pcap-filter.7 - syntax for capture filters)

edit flag offensive delete link more

Comments

I don't think the capture filter below will pass any traffic - expects [12] to be #0x8864 and #0x800

~$ dumpcap.exe -i 5 -d -f "ether[12:2] = 0x8864 and (( ether dst 00:00:00:00:00:01 and ip[19:1]&0x0f=0x01 ))"
Capturing on 'Ethernet'
(000) ldh      [12]
(001) jeq      #0x8864          jt 2    jf 12
(002) ld       [2]
(003) jeq      #0x1             jt 4    jf 12
(004) ldh      [0]
(005) jeq      #0x0             jt 6    jf 12
(006) ldh      [12]
(007) jeq      #0x800           jt 8    jf 12
(008) ldb      [33]
(009) and      #0xf
(010) jeq      #0x1             jt 11   jf 12
(011) ret      #262144
(012) ret      #0
Chuckc gravatar imageChuckc ( 2021-10-27 15:35:19 +0000 )edit

This is so worthy of an issue that there already is an issue about it - yes, it says "vlan", but "vlan", "pppoe", "mpls", and some others all work internally the same way.

This might take some restructuring of the libpcap filter compiler, e.g. make build a parse tree and then recursively walk it, so that a tree with an "OR" node with two expressions below it could generate code for those two nodes separately, so that the first node's adjustment of the packet offset wouldn't affect the second node. (For an "AND" node with "vlan"/"pppoe"/"mpls"/etc. on one side, the offset would affect the other side.)

I.e., not easy to fix.

Guy Harris gravatar imageGuy Harris ( 2021-10-27 19:31:13 +0000 )edit

not easy to fix.

I wonder if the introduction of a new primitive to explicitly reset the offset would help? For example:

(ether dst 00:00:00:00:00:01 and pppoes and ip[19:1] & 0x0f = 0x01) and reset and (ether src 00:00:00:00:00:01 and pppoes and ip[15:1] & 0x0f = 0x01)

... or perhaps an automatic offset reset at the end of a new set of grouping characters akin to parentheses such as braces, {}, where the semantics are the same as the parentheses except with the offset reset.

cmaynard gravatar imagecmaynard ( 2021-10-28 01:40:39 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2021-10-27 05:32:01 +0000

Seen: 85 times

Last updated: Oct 28