• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

python如何实时获取tcpdump输出

python 搞代码 4年前 (2022-01-07) 33次浏览 已收录 0个评论

这篇文章主要介绍了python如何实时获取tcpdump输出,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下

一、背景

  今天有个小需求,要确认客户端有没有往服务端发送udp包,但为了减轻工作量,不想每次到机器上手动执行tcpdump抓包命令。
  于是就写了个脚本来释放人力。

二、代码实现

  整个脚本我还加了一些其他功能:时间戳、发送端IP提取,数据包分析,数据持久化等。这里都先去掉,仅记录下简单的实时获取tcpdump输出功能。
  代码如下:

 # -*- coding: utf-8 -*- # !/usr/bin/env python # sudo tcpdump -tt -l -nn -c 5 -i enp4s0 udp port 514 or 51414 import subprocess cmd = ['sudo', 'tcpdump', '-tt', '-l', '-nn', '-c', '5', '-i', 'enp4s0', 'udp', 'port', '514', 'or', '51414'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) while True: line = proc.stdout.readline() line = line.strip() if not line: print('tcpdump finished...') break print(line)

  输出如下(实时):

 wenyuanblog@localhost:/home/test/script# python tcpdump_udp.py tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on enp4s0, link-type EN10MB (Ethernet), capture size 262144 bytes 1499774951.124178 IP 192.168.10.210.41974 > 192.168.10.251.514: UDP, length 139 1499774953.125664 IP 192.168.10.210.54995 > 192.168.10.251.51414: UDP, length 139 1499774956.128498 IP 192.168.10.210.56748 > 192.168.10.251.514: UDP, length 139 1499774958.129918 IP 192.168.10.210.53883 > 192.168.10.251.51414: UDP, length 139 1499774961.132921 IP 192.168.10.210.58803 > 192.168.10.251.<b style="color:transparent">来源gao@!dai!ma.com搞$$代^@码!网</b>514: UDP, length 139 5 packets captured 6 packets received by filter 0 packets dropped by kernel tcpdump finished...

  以上代码相当于手动执行了 sudo tcpdump -tt -l -nn -c 5 -i enp4s0 udp port 514 or 51414 这条命令。
  注意参数-l很重要(行显)。

三、代码实现(更新)

  上面的代码能实现tcpdump的功能,但是有一个问题:没有做超时保护。即当程序执行时间过长时kill该进程(这里使用ctrl+c的方式)。
  要实现这个功能有很多种方案,例如定时器+多线程等,这里仅演示一种方案,代码如下:

 # -*- coding: utf-8 -*- # !/usr/bin/env python # sudo tcpdump -tt -l -nn -c 50 -i enp4s0 udp port 514 or 51414 import subprocess import signal import time import os import re import json class CmdServer: def __init__(self, cmd, timeout=120): ''' :param cmd: 执行命令(列表形式) :param timeout: 任务超时时间(seconds,进程运行超过该时间,kill该进程) :param taskname: 任务名称(根据该任务名称记录命令输出信息) ''' self.cmd = cmd self.timeout = timeout self.base_path = reduce(lambda x, y: os.path.dirname(x), range(1), os.path.abspath(__file__)) self.output_path = os.path.join(self.base_path, 'data.json') self.udp_flow_list = [] self.begin_time = int(time.time()) # 执行tcpdump任务 def run(self): if os.path.exists(self.output_path): with open(self.output_path, 'r') as f: self.udp_flow_list = json.load(f) proc = subprocess.Popen(self.cmd, stdout=subprocess.PIPE) stdout = '' while proc.poll() == None: current_time = int(time.time()) if current_time - self.begin_time >= self.timeout: print('tcpdump timeout...') proc.send_signal(signal.SIGINT) stdout = proc.stdout.read() if proc.poll() is not None and not stdout: print('tcpdump finished...') stdout = proc.stdout.read() stdout_list = stdout.split('\n') if stdout_list: self._merge_data(stdout_list) self._save_data() # 数据合并(新增/更新) def _merge_data(self, stdout_list): for line in stdout_list: line = line.strip() if not line: continue timestamp = int(float(line.split('IP')[0].strip())) * 1000 # 源 src_ip_port_list = re.findall(r'IP(.+?)>', line) if not src_ip_port_list: continue src_ip_port_str = src_ip_port_list[0].strip() src_ip = '.'.join(src_ip_port_str.split('.')[0:4]) # 目的 dst_ip_port_list = re.findall(r'>(.+?):', line) if not dst_ip_port_list: continue dst_ip_port_str = dst_ip_port_list[0].strip() dst_port = dst_ip_port_str.split('.')[-1] # 新增/更新latest_timestamp src_item = filter(lambda x: src_ip == x['src_ip'], self.udp_flow_list) if src_item: src_item[0]['dst_port'] = dst_port src_item[0]['latest_timestamp'] = timestamp else: self.udp_flow_list.append(dict( src_ip=src_ip, dst_port=dst_port, latest_timestamp=timestamp )) # 保存数据 def _save_data(self): # 写入文件 with open(self.output_path, 'w') as f: json.dump(self.udp_flow_list, f, encoding="utf-8", ensure_ascii=False) if __name__ == '__main__': cmd = ['sudo', 'tcpdump', '-tt', '-l', '-nn', '-c', '5', '-i', 'enp4s0', 'udp', 'port', '514', 'or', '51414'] cmd_server = CmdServer(cmd, 10) cmd_server.run()

四、总结

  比较简单,仅仅是记录下。

以上就是python如何实时获取tcpdump输出的详细内容,更多关于python获取tcpdump输出的资料请关注gaodaima搞代码网其它相关文章!

以上就是python如何实时获取tcpdump输出的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:python如何实时获取tcpdump输出

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址