python如何实时获取tcpdump输出


Posted in Python onSeptember 16, 2020

一、背景

今天有个小需求,要确认客户端有没有往服务端发送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.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输出的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python3编写C/S网络程序实例教程
Aug 25 Python
python3制作捧腹网段子页爬虫
Feb 12 Python
Python 实现在文件中的每一行添加一个逗号
Apr 29 Python
使用python爬虫获取黄金价格的核心代码
Jun 13 Python
Python3.6基于正则实现的计算器示例【无优化简单注释版】
Jun 14 Python
对python3中pathlib库的Path类的使用详解
Oct 14 Python
pytorch1.0中torch.nn.Conv2d用法详解
Jan 10 Python
利用python实现.dcm格式图像转为.jpg格式
Jan 13 Python
tensorflow模型的save与restore,及checkpoint中读取变量方式
May 26 Python
python怎么对数字进行过滤
Jul 05 Python
Keras loss函数剖析
Jul 06 Python
Python读写csv文件流程及异常解决
Oct 20 Python
基于python实现复制文件并重命名
Sep 16 #Python
详解python程序中的多任务
Sep 16 #Python
python实现简单的tcp 文件下载
Sep 16 #Python
实现Python3数组旋转的3种算法实例
Sep 16 #Python
Python私有属性私有方法应用实例解析
Sep 15 #Python
PyQt5多线程防卡死和多窗口用法的实现
Sep 15 #Python
PyQt5结合matplotlib绘图的实现示例
Sep 15 #Python
You might like
VFP与其他应用程序的集成
2006/10/09 PHP
php无限分类且支持输出树状图的详细介绍
2013/06/19 PHP
javascript Select标记中options操作方法集合
2008/10/22 Javascript
IE8 下的Js错误HTML Parsing Error...
2009/08/14 Javascript
jQuery UI Autocomplete 1.8.16 中文输入修正代码
2012/04/16 Javascript
检测input每次的输入是否合法遇到汉字输入就有问题
2012/05/23 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
JavaScript中this关键词的使用技巧、工作原理以及注意事项
2014/05/20 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
jQuery修改class属性和CSS样式整理
2015/01/30 Javascript
Immutable 在 JavaScript 中的应用
2016/05/02 Javascript
微信小程序实战之仿android fragment可滑动底部导航栏(4)
2020/04/16 Javascript
小程序实现多列选择器
2019/02/15 Javascript
使用python检测手机QQ在线状态的脚本代码
2013/02/10 Python
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
Python实现处理管道的方法
2015/06/04 Python
深入理解python多进程编程
2016/06/12 Python
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
python让列表倒序输出的实例
2018/06/25 Python
如何使用python操作vmware
2019/07/27 Python
python按行读取文件并找出其中指定字符串
2019/08/08 Python
python hashlib加密实现代码
2019/10/17 Python
pytorch dataloader 取batch_size时候出现bug的解决方式
2020/02/20 Python
Python实现从N个数中找到最大的K个数
2020/04/02 Python
CSS3 实现侧边栏展开收起动画
2014/12/22 HTML / CSS
美国顶级奢侈茶:Mighty Leaf Tea(美泰茶)
2016/11/26 全球购物
幼儿园大班区域活动总结
2014/07/09 职场文书
党员自我剖析材料范文
2014/10/06 职场文书
六五普法宣传标语
2014/10/06 职场文书
房贷工资证明范本
2015/06/12 职场文书
小学英语教学反思范文
2016/02/15 职场文书
导游词之云南-元阳梯田
2019/10/08 职场文书
MySQL不使用order by实现排名的三种思路总结
2021/06/02 MySQL
python代码实现备忘录案例讲解
2021/07/26 Python
mysql中如何用命令创建联合唯一索引
2022/04/20 MySQL
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers