提取数据包大小并将其作为参数传递给脚本

时间:2016-06-19 16:21:28

标签: python shell networking automation tcpdump

每当数据包到达端口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

我想知道如何实现这个目标?

1 个答案:

答案 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/scapyhttps://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完成整个事情。