classic BPF on Linux: filter does not work

后端 未结 1 1544
一整个雨季
一整个雨季 2020-12-06 08:21

I\'m trying to test classic BPF for packet filtering by attaching it to raw socket. I want to catch TCP packets with first byte of source port == 8 (tcpdump \'tcp[1:1] = 0x5

相关标签:
1条回答
  • 2020-12-06 09:17

    In the case of your program, it seems that the BPF filter is applied directly on the Ethernet payload (starting with the IP headers) instead of the whole Ethernet frame.

    In this case, the first two checks you have in your program are not adapted:

    { 0x28,  0,  0, 0x0000000c }, // Load ethertype byte
    { 0x15,  0,  9, 0x00000800 }, // Goto drop if it is not == 0x800 (IPv4)
    { 0x30,  0,  0, 0x00000017 }, // Load IP protocole number
    { 0x15,  0,  7, 0x00000006 }, // Goto drop if it is not == 0x6 (TCP)
    

    Instead, we should:

    • Skip ethertype check (we already know we have IP anyway).
    • Change offset for IP protocol number.

    The beginning of the filter becomes instead:

    { 0x30,  0,  0, 0x00000009 }, // …09 Instead of …17: we start from beginning of IP header
    { 0x15,  0,  7, 0x00000006 },
    

    In fact, since you create a socket that will receive only TCP packets (int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);, see also man 7 raw), we can also simply get rid of this check as well.

    So the whole filter would be:

    struct sock_filter code[] = {
    
        { 0x30,  0,  0, 0x00000009 },
        { 0x15,  0,  7, 0x00000006 },
        { 0x28,  0,  0, 0x00000014 },
        { 0x45,  4,  0, 0x00001fff },
        { 0xb1,  0,  0, 0x0000000e },
        { 0x50,  0,  0, 0x00000013 },
        { 0x15,  0,  2, 0x00000050 },
        { 0x06,  0,  0, 0xffffffff },
        { 0x06,  0,  0, 0xffffffff },
        { 0x06,  0,  0, 0000000000 },
    
    };
    

    Or more simply:

    struct sock_filter code[] = {
    
        { 0x28,  0,  0, 0x00000014 },
        { 0x45,  4,  0, 0x00001fff },
        { 0xb1,  0,  0, 0x0000000e },
        { 0x50,  0,  0, 0x00000013 },
        { 0x15,  0,  2, 0x00000050 },
        { 0x06,  0,  0, 0xffffffff },
        { 0x06,  0,  0, 0xffffffff },
        { 0x06,  0,  0, 0000000000 },
    
    };
    

    Side note:

    #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
                                                         ^ ending parenthesis missing
    
    0 讨论(0)
提交回复
热议问题