I got code from http://allanrbo.blogspot.in/2011/12/raw-sockets-with-bpf-in-python.html. It works fine, but I want to sniff the traffic on multiple TCP ports like port 9000
, 80
, 22
...
So I have modified the filter_list
like blow
filters_list = [
# Must have dst port 67. Load (BPF_LD) a half word value (BPF_H) in
# ethernet frame at absolute byte offset 36 (BPF_ABS). If value is equal to
# 67 then do not jump, else jump 5 statements.
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 36),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 0, 5), <===== Here I added another port
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 80, 0, 5),
# Must be UDP (check protocol field at byte offset 23)
bpf_stmt(BPF_LD | BPF_B | BPF_ABS, 23),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x06, 0, 3), #<==Changed for TCP "0x06"
# Must be IPv4 (check ethertype field at byte offset 12)
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 12),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x0800, 0, 1),
bpf_stmt(BPF_RET | BPF_K, 0x0fffffff), # pass
bpf_stmt(BPF_RET | BPF_K, 0), # reject ]
The thing is, sometimes it is working sometimes it is not, like getting traffic only on 9000 but not 80, sometimes getting traffic on 80. I didnt understood the code completely. Any help?
As far as I can tell, the problem seems to come from the logic of your first two conditional jumps. Specifically:
An instruction
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, <val>, <jtrue>, <jfalse>)
meansSo the two lines mean:
While you probably want something that looks more like:
I have not tested, but to get this logics I would say you need to adapt the jump offsets as follows:
Edit 1: And then for filtering three ports, that would become:
Edit 2: To also filter on source port (in addition to destination port), you could try something like this (still not tested on my side):