Skip to content

protochain headache (please help) #1133

@ralequi

Description

@ralequi

I'm trying to use BPF in order to filter eth/vlan/ip/tcp headers that are behind a GRE encapsulation protocol.

Consider this example packet:

       00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0000   7c 91 69 9b d3 6d 10 ef 49 5f b1 e7 08 00 45 00
0010   00 84 00 00 00 00 fd 2f a5 fd 6a e3 9c b5 6a e3
0020   a4 d1 00 00 65 58 CA FE CA FE CA FE CA CA CA CA
0030   CA CA 81 00 00 69 08 00 45 20 00 5a a1 c5 40 00
0040   79 06 77 02 c0 a8 03 60 c0 a8 64 05 c2 27 0d 3d
0050   49 ca eb 16 b7 2c 3e 30 50 18 03 fd f1 66 00 00
0060   17 03 03 00 2d 00 00 00 00 00 01 c2 2b 47 fa 65
0070   d6 eb 3c 72 e4 4c 87 cb 4a 86 7f 87 c7 9f 9d 3b
0080   df f6 93 3f 20 48 5b b6 fc db 61 31 03 95 41 3c
0090   28 f8

If we try something "simple", that only checks for the CA:CA:CA:CA:CA:CA ethernet address, let's say: (protochain GRE && ether host CA:CA:CA:CA:CA:CA)

We'll get the following code:

dumpcap -d -f "(protochain GRE && ether host CA:CA:CA:CA:CA:CA)" 
Capturing on 'wlo1'
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 22
(002) ldb      [23]
(003) ldxb     4*([14]&0xf)
(004) jeq      #0x2f            jt 20   jf 5
(005) jeq      #0x3b            jt 20   jf 6
(006) add      #0
(007) jeq      #0x33            jt 8    jf 20
(008) txa      
(009) ldb      [x + 14]
(010) st       M[1]
(011) txa      
(012) add      #1
(013) tax      
(014) ldb      [x + 14]
(015) add      #2
(016) mul      #4
(017) tax      
(018) ld       M[1]
(019) ja       4
(020) add      #0
(021) jeq      #0x2f            jt 56   jf 22
(022) ldh      [12]
(023) jeq      #0x86dd          jt 24   jf 65
(024) ldb      [20]
(025) ldx      #0x28
(026) jeq      #0x2f            jt 54   jf 27
(027) jeq      #0x3b            jt 54   jf 28
(028) jeq      #0x0             jt 32   jf 29
(029) jeq      #0x3c            jt 32   jf 30
(030) jeq      #0x2b            jt 32   jf 31
(031) jeq      #0x2c            jt 32   jf 41
(032) ldb      [x + 14]
(033) st       M[1]
(034) ldb      [x + 15]
(035) add      #1
(036) mul      #8
(037) add      x
(038) tax      
(039) ld       M[1]
(040) ja       26
(041) jeq      #0x33            jt 42   jf 54
(042) txa      
(043) ldb      [x + 14]
(044) st       M[1]
(045) txa      
(046) add      #1
(047) tax      
(048) ldb      [x + 14]
(049) add      #2
(050) mul      #4
(051) tax      
(052) ld       M[1]
(053) ja       26
(054) add      #0
(055) jeq      #0x2f            jt 56   jf 65
(056) ld       [8]
(057) jeq      #0xcacacaca      jt 58   jf 60
(058) ldh      [6]
(059) jeq      #0xcaca          jt 64   jf 60
(060) ld       [2]
(061) jeq      #0xcacacaca      jt 62   jf 65
(062) ldh      [0]
(063) jeq      #0xcaca          jt 64   jf 65
(064) ret      #262144
(065) ret      #0

This code, unless I'm missing something, will only execute in this order:

(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 22 # True!
(002) ldb      [23]   # 0x17
(003) ldxb     4*([14]&0xf)
(004) jeq      #0x2f            jt 20   jf 5 # True!
(020) add      #0      # do nothing ??
(021) jeq      #0x2f            jt 56   jf 22 # True again!
(056) ld       [8] # Ups, we are not behind GRE header!!
(057) jeq      #0xcacacaca      jt 58   jf 60 # False :-(
(060) ld       [2] # Ups, we are not behind GRE header!!
(061) jeq      #0xcacacaca      jt 62   jf 65 # False again....
(065) ret      #0 # missmatch!

Unless I have missunderstood the behaviour of protochain, it should "virtually move" the packet pointer behind the GRE header, so we can filter there.

I'm really confused and everything I found on the internet says that filter (protochain GRE && ether host CA:CA:CA:CA:CA:CA) should work.

This have been deeply tested on Fedora 37 and replicated on Ubuntu 22

  • libpcap: 1.10.1
  • Dumpcap (Wireshark) 3.6.8 (Git commit d25900c51508)
  • Other data that might be interesting:
Running on Linux 5.19.15-301.fc37.x86_64, with Intel(R) Core(TM) i5-8250U CPU @
1.60GHz (with SSE4.2), with 32015 MB of physical memory, with GLib 2.74.0, with
zlib 1.2.12, with libpcap 1.10.1 (with TPACKET_V3), with LC_TYPE=C, binary
plugins supported (0 loaded).

Any help would be welcomed.
Thank you in advance.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions