0

Everytime a packet arrives in the port eth1, I want to extract its packet size and pass this as parameter to my script cap.sh.

My approach:

I tried tcpdump -nttv -i eth1

It provided

1466352405.455975 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 46)
192.168.52.53.32769 > 192.168.52.54.9600: UDP, length 18

I want to extract the length (46) and pass this to my script cap.sh

sh cap.sh 46

I wish to know how to implement this?

user2532296
  • 828
  • 1
  • 10
  • 27

1 Answers1

1

You could rely on tcpdump's output format and extract the packet length with something like grep -Po '(?<=length )\d+(?=\))'.

Here grep's -P switch turns on the Perl regexes, -o makes grep output only the matching part. Then, (?<=length ) part of regex does a lookbehind, so length[space] has to be before the match. \d+ matches one or more digits greedily, and (?=\)) part does a lookahead, so a closing brace has to be after the match. Please note that lookaheads and lookbehinds are not matched themselves. Think of them as of anchors.

Note that you can make the regex more strict by adding an endline anchor, $: (?<=length )\d+(?=\)$)

I wouldn't really recommend doing this if you want your approach to be portable and universal.

So the whole thing would look like

while read lngth ; do sh cap.sh "$lngth" ; done< <(unbuffer tcpdump -i eth1 -nttv 2>/dev/null | unbuffer -p grep -Po '(?<=length )\d+(?=\))')

Please note it uses unbuffer from expect so you don't have to wait until the pipe buffer is full to flush it.

Another approach to extract lengths would be to use something like scapy, a packet inspection/manipulation module for python (https://github.com/secdev/scapy, https://github.com/phaethon/scapy). A python script that prints lengths of IP packets in an infinite loop using scapy will look like this:

from scapy.all import *
sniff(filter='ip', prn=lambda x: x.sprintf("%IP.len%"))

So you can replace the tcpdump | grep part with this script, or maybe even rewrite your cap.sh in Python and do the whole thing in Python.

Pavel Gurkov
  • 737
  • 5
  • 14
  • Thanks, could you explain what the regex does, I tried the grep with tcpdump but it didn't extract the packet length. – user2532296 Jun 19 '16 at 17:26
  • Sure. Edited the answer. I would also recommend to check out [this](http://www.regular-expressions.info) resource as an excellent source about regexes. – Pavel Gurkov Jun 19 '16 at 17:50
  • Thanks for the info. I tried it here (https://regex101.com/), but still doesn't work. – user2532296 Jun 19 '16 at 18:14
  • Should work. https://regex101.com/r/lG8wZ5/1 If you used my version with endline anchor, I did a mistake in it, it should look like `(?<=length )\d+(?=\)$)` – Pavel Gurkov Jun 19 '16 at 18:22
  • Actually it doesn't work(https://regex101.com/r/xW4bI6/1) for the test case given above where we have two lengths. I checked it. Thanks – user2532296 Jun 19 '16 at 18:26
  • If you want to modify it so it matches all the lengths for all protos (IP, TCP, UDP, etc), you can simplify it to this: https://regex101.com/r/xW4bI6/3 – Pavel Gurkov Jun 19 '16 at 18:42