分析网络抓包用 python 更高效

news2024/12/22 23:06:55
Abstract分析网络抓包用 python 更高效
AuthorsWalter Fan
Categorylearning note
Statusv1.0
Updated2023-01-10
LicenseCC-BY-NC-ND 4.0

网络抓包分析用的最多的两大工具是 tcpdump 和 wireshark.

一般我们通过 tcpdump 或者 wireshark 来捕获网络包为 *.pcap 或者 *.pcapng 文件

tcpdump  -G 60 -W 1 -w /tmp/test.pcap

而分析 pcap 文件可以用 wireshark, wireshark 之强大, 界面之复杂不用赘述, 相关书籍和文章汗牛充栋.

我更喜欢用其命令行工具 tshark, 例如

tshark -P -V -x -2 -T text -j rtp -c 3 -r /tmp/test.pcap

例如将 pcapng 文件中的前 100 包按以下条件过滤出来,并导出为 json 文件

tshark -r 2022-03-30-cc.pcapng -2 -Y "ip.addr == 10.140.202.120 and rtp.p_type == 123" -V -c 100 -T json >
packet_sample.json"

输出结果如下

//省略 1 ~ 4 层的信息: 1)frame, 2)eth, 3)ip, 4)udp
"rtp": {
  "rtp.setup": "",
  "rtp.setup_tree": {
    "rtp.setup-frame": "1",
    "rtp.setup-method": "HEUR RTP"
  },
  "rtp.version": "2",
  "rtp.padding": "0",
  "rtp.ext": "1",
  "rtp.cc": "0",
  "rtp.marker": "0",
  "rtp.p_type": "123",
  "rtp.seq": "8637",
  "rtp.extseq": "74173",
  "rtp.timestamp": "2709737133",
  "rtp.ssrc": "0xe19bcceb",
  "rtp.ext.profile": "0x0000bede",
  "rtp.ext.len": "2",
  "rtp.hdr_exts": {
    "RFC 5285 Header Extension (One-Byte Header)": {
      "rtp.ext.rfc5285.id": "2",
      "rtp.ext.rfc5285.len": "3",
      "rtp.ext.rfc5285.data": "e0:9c:ac"
    },
    "RFC 5285 Header Extension (One-Byte Header)": {
      "rtp.ext.rfc5285.id": "3",
      "rtp.ext.rfc5285.len": "2",
      "rtp.ext.rfc5285.data": "c4:70"
    }
  },
  "rtp.payload": "92:00:60:90:80:c6:67:..."
}

更多具体用法参见 tshark –help

如果我们需要进一步地进行自动化分析,pyshark 是一个不错的库, 用 python 就可以读取分析网络包

pyshark 基本用法

1) 从抓包文件中读取网络包

>>> import pyshark
>>> cap = pyshark.FileCapture('/tmp/mycapture.cap')
>>> cap
<FileCapture /tmp/mycapture.cap (589 packets)>
>>> print cap[0]
Packet (Length: 698)
Layer ETH:
        Destination: BLANKED
        Source: BLANKED
        Type: IP (0x0800)
Layer IP:
        Version: 4
        Header Length: 20 bytes
        Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        Total Length: 684
        Identification: 0x254f (9551)
        Flags: 0x00
        Fragment offset: 0
        Time to live: 1
        Protocol: UDP (17)
        Header checksum: 0xe148 [correct]
        Source: BLANKED
        Destination: BLANKED
  ...

2) 从一个网络接口中读取网络包

>>> capture = pyshark.LiveCapture(interface='eth0')
>>> capture.sniff(timeout=50)
>>> capture
<LiveCapture (5 packets)>
>>> capture[3]
<UDP/HTTP Packet>

for packet in capture.sniff_continuously(packet_count=5):
    print 'Just arrived:', packet

3) 使用环形缓冲区从一个网络接口中读取网络包

>>> capture = pyshark.LiveRingCapture(interface='eth0')
>>> capture.sniff(timeout=50)
>>> capture
<LiveCapture (5 packets)>
>>> capture[3]
<UDP/HTTP Packet>

for packet in capture.sniff_continuously(packet_count=5):
    print 'Just arrived:', packet

4) 从一个远程网络接口读取网络包

>>> capture = pyshark.RemoteCapture('192.168.1.101', 'eth0')
>>> capture.sniff(timeout=50)
>>> capture

更多用法参见 https://github.com/KimiNewt/pyshark

综合实例

我在分析 WebRTC 中的网络梯度延迟 OWDV(One Way Delay Variation), 也用它写了一小段脚本, 性价比极高

#!/usr/bin/env python3
import pyshark
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt

import argparse
from datetime import datetime


"""
abs_send_time_24 = (ntp_timestamp_64 >> 14) & 0x00ffffff ;
NTP timestamp is the number of seconds since the epoch, in 32.32 bit fixed point format.
It is 24 bit 6.18 fixed point,  yielding 64s wraparound and 3.8us resolution

int kAbsSendTimeFraction = 18;
int kAbsSendTimeInterArrivalUpshift = 8;
int kInterArrivalShift = RTPHeaderExtension::kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;
constexpr double kTimestampToMs = 1000.0 / static_cast<double>(1 << kInterArrivalShift);
uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
Timestamp send_time = Timestamp::Millis(static_cast<int64_t>(timestamp) * kTimestampToMs);

"""
# fraction part has 18 bits
kAbsSendTimeFraction = 18
kAbsSendTimeInterArrivalUpshift = 8
# after upshfit 8 bits, there are 26 bits for fraction
kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift

kTimestampToMs = 1000.0 / (1 << kInterArrivalShift)


def send_time_to_ms(send_time_24bits):
    timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift
    send_time = timestamp * kTimestampToMs
    return send_time


class RtpAnalyzer:

    def __init__(self, input_file, output_file):
        self._pcap_file = input_file
        self._csv_file = output_file

    def read_pcap(self, display_filter, count):

        dataList = []
        packets = pyshark.FileCapture(self._pcap_file, display_filter=display_filter)
        i = 0
        for packet in packets:
            dataItem = {}

            dataItem["arrival_time"] = datetime.fromtimestamp(float(packet.frame_info.time_epoch))
            dataItem["arrival_time_ms"] = float(packet.frame_info.time_epoch) * 1000
            dataItem["rtp_timestamp"] = int(packet.rtp.timestamp)
            dataItem["extseq"] = int(packet.rtp.extseq)
            dataItem["packet_size"] = int(packet.udp.length)

            if int(packet.rtp.ext_rfc5285_id) == 2:
                send_time_24bits = packet.rtp.ext_rfc5285_data.main_field.hex_value
                dataItem["abs_send_time"] = send_time_to_ms(send_time_24bits)

            dataList.append(dataItem)

            i += 1
            if i >= count:
                break

        dataFrame = pd.DataFrame(dataList)
        #print(dataFrame)
        return dataFrame

    def calculate_delta(self, df, row_interval=1):
        df["arrival_time_ms_diff"] = df["arrival_time_ms"].diff(periods=row_interval)
        df["send_time_diff"] = df["abs_send_time"].diff(periods=row_interval)
        df["OWDV"] = df["arrival_time_ms_diff"] - df["send_time_diff"]
        df["OWDV"] = df["OWDV"].abs()
        df = df[df['OWDV'] < 60]
        print(df)
        df.to_csv(self._csv_file)
        print(df["OWDV"].describe())

        print("* note: filter out OWDV if it > 60s because abs_send_time wrap around by 64s")
        return df

    def draw_chart(self, chart_file, df, x, y):
        plt.style.use('seaborn-v0_8-whitegrid')

        fig = plt.figure(figsize=(36, 18))
        font = {'size': 16}

        plt.plot(x, y, data=df)
        #plt.show()
        fig.savefig(chart_file)
        plt.close()

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('-i', action='store', dest='input_file', help='specify input file')
    parser.add_argument('-o', action='store', dest='output_file', help='specify output file')
    parser.add_argument('-f', action='store', dest='filter', default="rtp", help='specify filter expression')
    parser.add_argument('-c', action='store', dest='count', default=10, help='specify packet count')
    args = parser.parse_args()

    if not args.input_file or not args.output_file or not args.output_file.endswith(".csv"):

        print("usage: ./rtp_analyze.py -i <pcap_file> -f <filter_expression>")
        print('such as: ./rtp_analyze.py -i /tmp/test_owdv.pcap -o "test_owdv.csv" -f "rtp.ssrc==0x8ab92fad" -c 100000')
        exit(0)

    rtpAnalyzer = RtpAnalyzer(args.input_file, args.output_file)

    df = rtpAnalyzer.read_pcap(args.filter, int(args.count))
    if not df.empty:
        df = rtpAnalyzer.calculate_delta(df)
        rtpAnalyzer.draw_chart("{}.png".format(args.output_file[:-4]), df, "arrival_time",  "OWDV")

上述小程序生成的图片如下

参考资料

  • TShark: https://www.wireshark.org/docs/man-pages/tshark.html
  • Pyshark: https://github.com/KimiNewt/pyshark


本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch:在 Elasticsearch 中按距离有效地对地理点进行排序

计算搜索中两点之间的距离有很多用例。 如果你正在处理地理数据&#xff0c;那么无论你从事何种业务&#xff0c;这都必然会出现。 然后&#xff0c;在对这些点进行排序时&#xff0c;你可能需要考虑距离&#xff0c;因为……好吧&#xff0c;为什么不呢&#xff1f; 所以这里…

算法训练营DAY48|121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

这一期到了买卖股票专题&#xff0c;买卖股票的有一些题型&#xff0c;可以使用贪心算法来求解&#xff0c;甚至有时候比动态规划更简单一些&#xff0c;但是本期是讲动态规划的运用&#xff0c;所以不做对于贪心的分析。今天只讲两道例题&#xff0c;其中第二题是第一题的变种…

[NeurIPS 2017] Poincaré Embeddings for Learning Hierarchical Representations

ContentsIntroductionPoincar EmbeddingsThe Limitations of Euclidean Space for Hierarchical DataEmbedding Hierarchies in Hyperbolic SpaceEvaluationReferencesIntroduction 如今&#xff0c;表征学习变得越来越重要 (e.g. word embedding, embeddings of graphs, embe…

如何在电脑上安装 Windows 版桌面编辑器 v7.3

线上编辑器的桌面端版本不需要持续的互联网连接&#xff0c;还可在计算机上处理脱机文件。因此&#xff0c;如果您需要此类功能&#xff0c;可从我们的网站中下载并安装桌面编辑器。 ONLYOFFICE桌面编辑器最新版 最近 ONLYOFFICE 发布了 v7.3&#xff0c;最新版本的桌面编辑器…

SpringBoot+Vue点餐系统

简介&#xff1a;本项目采用了基本的springbootvue设计的点餐。系统。详情请看截图。经测试&#xff0c;本项目正常运行。本项目适用于Java毕业设计、课程设计学习参考等用途。 项目描述 项目名称SpringBootVue点餐系统源码作者LHL项目类型Java EE项目 &#xff08;前后分离&a…

ESP-IDF:命令模式测试

ESP-IDF:命令模式 /命令模式/ /设计模式之开闭原则&#xff0c;对增加开放对修改关闭/ #include #include class ClientCommands{ //统一管理命令&#xff0c;这是比观察者模式多出来的地方 public: void AddMoney(){ cout<<“add money”<<endl; } void AddEqu…

图解LeetCode——1145. 二叉树着色游戏(难道:中等)

一、题目 有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中&#xff0c;给出二叉树的根节点 root&#xff0c;树上总共有 n 个节点&#xff0c;且 n 为奇数&#xff0c;其中每个节点上的值从 1 到 n 各不相同。 最开始时&#xff1a; 「一号」玩家从 [1, n] 中取一个值…

Ubuntu22.04安装nvidia显卡驱动

Ubuntu22.04安装nvidia显卡驱动 目录 方法一&#xff1a;使用官方的NVIDIA驱动进行手动安装&#xff08;稳定、靠谱&#xff09; 方法二&#xff1a;使用系统自带的“软件和更新”程序-附加驱动更新&#xff08;需要联网&#xff0c;稳定性无法验证&#xff09; 浓缩极简方法…

MySQL入门篇-视图简介

备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL视图。 前言: 视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中&#xff0c;是一个虚表。 即数据库中只存放视图的定义而不存放视图对应的数据&#xff0c;这些数据仍存放在导出视图的基本表中。 视…

[Windows] 微信超级管家,自动好友回复、计数、自动同意、群发、好友导出、消息日志、无限多开

简介 微信超级管家是一款大神针对微信制作的工具&#xff0c;它的主要功能包括了自动回复、好友计数、自动同意、群发、好友导出、消息日志、无限多开等等&#xff0c;让你拥有无限潜力哈&#xff0c;经常使用微信电脑版的朋友一定会用的上。 下载 微信超级管家 软件功能 1…

安全测试之浅析静态应用

SAST&#xff0c;Static Application Security Testing&#xff0c;即静态应用安全测试&#xff0c;也叫静态分析&#xff0c;是一种测试方法&#xff0c;一直是应用程序安全性工作的核心部分。根据Forrester的 The State Of Application Security, 2022一文的预测&#xff0c;…

云计算|OpenStack|社区版OpenStack安装部署文档(七--- 仪表盘服务dashboard的安装部署---Rocky版)

前言&#xff1a; 仪表盘是一般项目的标配&#xff0c;有了仪表盘可以降低运维工作&#xff0c;并且很多的管理工作是可以可视化的。本节计划在控制节点安装openstack官网的仪表盘项目 openstack由于是一个开源的社区版本云计算项目&#xff0c;因此&#xff0c;它的web仪表盘…

【Core】.net core 3.1 api 返回实体类数据存在null,导致小程序调用接口也直接显示了null,原来要这样设置才可

对接过API接口的小伙伴都知道&#xff0c;接口返回的Json格式数据&#xff0c;有些字段可能会出现null的情况&#xff0c;并且还是个字符串&#xff0c;直接显示在用户界面上给人感觉出bug了 文章目录【开发环境】【场景描述】【返回null值重现】1&#xff09;创建新项目2&…

细讲TCP三次握手四次挥手(二)

TCP/IP 协议族 应用层 应用层( application-layer &#xff09;的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程&#xff08;进程&#xff1a;主机中正在运行的程序&#xff09;间的通信和交互的规则。 对于不同的网络应用需要不同的应用层协议…

基本放大器电路- (一)

运算放大器组成的电路五花八门&#xff0c;令人眼花瞭乱&#xff0c;是模拟电路中学习的重点。在分析它的工作原理时倘没有抓住核心&#xff0c;往往令人头大。为此本人特搜罗天下运放电路之应用&#xff0c;来个“庖丁解牛”&#xff0c;希望各位从事电路板维修的同行&#xf…

精讲rpc框架,这么讲不怕你不明白!

谈到rpc框架可能有点陌生感&#xff0c;但是如果换成框架语言Ocaml&#xff0c;大家一定不陌生。 众所周知&#xff0c;ocaml是一款专门做functional programming的一款软件&#xff0c;尤其是它的界面非常简洁&#xff0c;还是专门的server进行线上编写。 rpc框架和ocaml是什…

一篇就看懂的文件操作

文件操作1为什么使用文件我们前面学习结构体时&#xff0c;写了通讯录的程序&#xff0c;当通讯录运行起来的时候&#xff0c;可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯录中的数据自然就不存在了&#xff…

【Java并发编程】 interrupt 方法详解

【Java并发编程】 interrupt 方法详解 文章目录【Java并发编程】 interrupt 方法详解1.介绍2.打断阻塞状态线程3.打断正常状态的线程4.两阶段终止模式5.打断 park 线程1.介绍 程序中&#xff0c;有些线程的终端需要外部干预&#xff0c;比如有线程存在while(true)循环&#xf…

值得拥有并收藏的 3个安卓/鸿蒙手机解锁软件

手机无论支持哪种操作系统&#xff0c;都占据了每个人口袋里的空间。随着大量移动设备的使用&#xff0c;搜索引擎上也出现了同样数量的查询&#xff0c;其中最常见的是提供安卓/鸿蒙屏幕锁定删除工具。由于安卓是当今最畅销的设备&#xff0c;我们的首要任务是为您提供最好的安…

矿山安全生产监测预警系统 opencv

矿山安全生产监测预警系统通过pythonopencv网络模型计算机视觉技术&#xff0c;对现场画面中人的不安全行为”、“物的不安全状态”、“环境的不安全因素”三方面出发进行实时监测&#xff0c;当监测到现场画面中人员未穿反光衣行为、明火烟雾、未穿安全帽行为、矿车掉道识别、…