每当数据包到达端口eth1
时,我想提取其数据包大小并将其作为参数传递给我的脚本cap.sh
。
我的方法:
我尝试了tcpdump -nttv -i eth1
提供了
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
我想提取长度(46)并将其传递给我的脚本cap.sh
sh cap.sh 46
我想知道如何实现这个目标?
答案 0 :(得分:1)
您可以依赖tcpdump
的输出格式,并使用grep -Po '(?<=length )\d+(?=\))'
等内容提取数据包长度。
此处grep
-P
开关打开Perl正则表达式,-o
使grep仅输出匹配部分。然后,(?<=length )
正则表达式的一部分做了一个lookbehind,所以length[space]
必须在比赛之前。 \d+
贪婪地匹配一个或多个数字,而(?=\))
部分进行前瞻,因此必须在比赛结束后关闭括号。请注意,前瞻和外观并不匹配。把它们想象成锚点。
请注意,您可以通过添加结束线锚点$
来使正则表达式更严格:(?<=length )\d+(?=\)$)
如果您希望自己的方法具有可移植性和通用性,我不建议这样做。
所以整个事情看起来像是
while read lngth ; do sh cap.sh "$lngth" ; done< <(unbuffer tcpdump -i eth1 -nttv 2>/dev/null | unbuffer -p grep -Po '(?<=length )\d+(?=\))')
请注意,它使用expect中的unbuffer
,因此您不必等到管道缓冲区已满,才能清除它。
另一种提取长度的方法是使用scapy
之类的东西,python(https://github.com/secdev/scapy,https://github.com/phaethon/scapy)的数据包检查/操作模块。
使用scapy
在无限循环中打印长度的IP数据包的python脚本将如下所示:
from scapy.all import *
sniff(filter='ip', prn=lambda x: x.sprintf("%IP.len%"))
所以你可以用这个脚本替换tcpdump | grep
部分,或者甚至用Python重写你的cap.sh
并用Python完成整个事情。