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.