如何读取tcpdump生成的包含大UDP数据包的pcap文件并重新组装IP碎片数据包?

问题描述

我想读取由 tcpdump 生成的 pcap 文件,其中包含经过 IPV4 fragmentation 的大型 UDP 数据包。原始数据包大小约为 22000 字节。

在 C++ 中,我会使用带有 IPV4Reassembler 的 libtins。有没有办法在 Rust 中做类似的事情?

目前在 Rust 中,这是我到目前为止所写的内容:非常不完整的第一次尝试(使用 crate use pnet::packet::{ ethernet::{EtherTypes,EthernetPacket},ip::IpNextHeaderProtocols,ipv4::Ipv4Packet,udp::UdpPacket,Packet,}; struct Ipv4Reassembler { cap: pcap::Capture<pcap::Offline>,} impl Iterator for Ipv4Reassembler { type Item = Vec<u8>; fn next(&mut self) -> Option<Self::Item> { let mut payload = Vec::<u8>::new(); while let Some(packet) = self.cap.next().ok() { // todo: handle packets other than Ethernet packets let ethernet = EthernetPacket::new(packet.data).unwrap(); match ethernet.get_ethertype() { EtherTypes::Ipv4 => { let ipv4_packet = Ipv4Packet::new(ethernet.payload()).unwrap(); // dbg!(&ipv4_packet); // todo: discard incomplete packets // todo: construct header for reassembled packet // todo: check id,etc let off: usize = 8 * ipv4_packet.get_fragment_offset() as usize; let end = off + ipv4_packet.payload().len(); if payload.len() < end { payload.resize(end,0); } payload[off..end].clone_from_slice(ipv4_packet.payload()); if ipv4_packet.get_flags() & 1 == 0 { return Some(payload); } } _ => {} } } None } } fn main() { let pcap_path = "os-992114000702.pcap"; let reass = Ipv4Reassembler { cap: pcap::Capture::from_file(&pcap_path).unwrap(),}; for payload in reass { let udp_packet = UdpPacket::new(&payload).unwrap(); dbg!(&udp_packet); dbg!(&udp_packet.payload().len()); } } ):

#include <tins/ip_reassembler.h>
#include <tins/packet.h>
#include <tins/rawpdu.h>
#include <tins/sniffer.h>
#include <tins/tins.h>
#include <tins/udp.h>

#include <iostream>
#include <string>

void read_packets(const std::string &pcap_filename) {
    Tins::IPv4Reassembler reassembler;
    Tins::FileSniffer sniffer(pcap_filename);

    while (Tins::Packet packet = sniffer.next_packet()) {
        auto &pdu = *packet.pdu();
        const Tins::Timestamp &timestamp = packet.timestamp();
        if (reassembler.process(pdu) != Tins::IPv4Reassembler::FRAGMENTED) {
            const Tins::UDP *udp = pdu.find_pdu<Tins::UDP>();
            if (!udp) {
                continue;
            }
            const Tins::RawPDU *raw = pdu.find_pdu<Tins::RawPDU>();
            if (!raw) {
                continue;
            }
            const Tins::RawPDU::payload_type &payload = raw->payload();
            std::cout << "Packet: " << payload.size() << std::endl;
            // do something with the reassembled packet here
        }
    }
}

int main() {
    const std::string pcap_path = "os-992114000702.pcap";
    read_packets(pcap_path);
}

在 C++ 中,这是我将使用的代码(使用 libtins):

g++ -O3 -o pcap pcap.cpp -ltins
private fun fetchData() {

        val url =
            "https://newsapi.org/v2/top-headlines?country=in&category=science&apiKey=1f4a12d2698e432ea9cf18126dcc7acd"
        val jsonObjectRequest = object : JsonObjectRequest(
            Request.Method.GET,url,null,{
                Log.e("TAG","fetchData: $it")
                val newsJsonArray = it.getJSONArray("articles")
                val newsArray = ArrayList<News>()
                for (i in 0 until newsJsonArray.length()) {
                    val newsJsonObject = newsJsonArray.getJSONObject(i)
                    val news = News(
                        newsJsonObject.getString("title"),newsJsonObject.getString("author"),newsJsonObject.getString("url"),newsJsonObject.getString("urlToImage")
                    )
                    newsArray.add(news)
                }

                mAdapter.updateNews(newsArray)
            },{
                Log.d("Error occur","Try again..." + it.networkResponse.statusCode)
            }
        ) {
            override fun getHeaders(): MutableMap<String,String> {
                val headers = HashMap<String,String>()
                headers["User-Agent"] = "Mozilla/5.0"
                return headers
            }
        }
        MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest)
    }

似乎一种解决方案是实现 RFC815,但我不确定如何在 Rust 中实现。我发现:

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...