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 相关文章推荐
python实现的各种排序算法代码
Mar 04 Python
Windows上使用virtualenv搭建Python+Flask开发环境
Jun 07 Python
Flask框架中密码的加盐哈希加密和验证功能的用法详解
Jun 07 Python
python中nan与inf转为特定数字方法示例
May 11 Python
Python数字图像处理之霍夫线变换实现详解
Jan 12 Python
详解python3 + Scrapy爬虫学习之创建项目
Apr 12 Python
Python3 itchat实现微信定时发送群消息的实例代码
Jul 12 Python
TensorFlow通过文件名/文件夹名获取标签,并加入队列的实现
Feb 17 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
Feb 28 Python
PyCharm最新激活码(2020/10/27全网最新)
Oct 27 Python
用 Django 开发一个 Python Web API的方法步骤
Dec 03 Python
Python中递归以及递归遍历目录详解
Oct 24 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
同时提取多条新闻中的文本一例
2006/10/09 PHP
dede3.1分页文字采集过滤规则详说(图文教程)
2007/04/03 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
学习php设计模式 php实现策略模式(strategy)
2015/12/07 PHP
PHP中让json_encode不自动转义斜杠“/”的方法
2017/02/28 PHP
Laravel 默认邮箱登录改成用户名登录的实现方法
2019/08/12 PHP
js新闻滚动 js如何实现新闻滚动效果
2013/01/07 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
JavaScript语言核心数据类型和变量使用介绍
2013/08/23 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
JS实现超炫网页烟花动画效果的方法
2015/03/02 Javascript
JavaScript中判断函数、变量是否存在
2015/06/10 Javascript
使用javascript将时间转换成今天,昨天,前天等格式
2015/06/25 Javascript
javascript实现在线客服效果
2015/07/15 Javascript
js显示当前日期时间和星期几
2015/10/22 Javascript
JS快速实现移动端拼图游戏
2016/09/05 Javascript
微信小程序 页面传值详解
2017/03/10 Javascript
react native与webview通信的示例代码
2017/09/25 Javascript
跨域解决之JSONP和CORS的详细介绍
2018/11/21 Javascript
Python基于smtplib实现异步发送邮件服务
2015/05/28 Python
安装python3的时候就是输入python3死活没有反应的解决方法
2018/01/24 Python
python用BeautifulSoup库简单爬虫实例分析
2018/07/30 Python
python实现飞机大战微信小游戏
2020/03/21 Python
django url到views参数传递的实例
2019/07/19 Python
python3实现绘制二维点图
2019/12/04 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
Python中用xlwt制作表格实例讲解
2020/11/05 Python
详解Python调用系统命令的六种方法
2021/01/28 Python
美国知名的在线旅游服务网站:Priceline
2016/07/23 全球购物
美国背景检查、公共记录和人物搜索网站:BeenVerified
2018/02/25 全球购物
成人高等教育毕业生自我鉴定
2013/10/22 职场文书
向领导表决心的话
2014/03/11 职场文书
师德模范事迹材料
2014/06/03 职场文书
原料仓管员岗位职责
2015/04/01 职场文书
推荐六本经典文学奖书籍:此生必读
2019/08/22 职场文书
Golang中interface{}转为数组的操作
2021/04/30 Golang