rusticata / pcap-parser

PCAP/PCAPNG file format parser written in pure Rust. Fast, zero-copy, safe.
Other
103 stars 25 forks source link

Examples of printing out payload of a packet? #34

Open spirrello opened 3 months ago

spirrello commented 3 months ago

Hi,

Can you provide an example of how to print the payload of a packet when reading in a pcap file? For instance, if wanted to print the DNS or HTTP payload of a packet, how would I go about doing this using pcap-parser?

chifflier commented 3 months ago

First, you have to write a loop to read packets from the file. One example is given in the docs, "streaming parser". Now, in the above example, when you have a block, you need to match it for the type, and depending on the type, call pcap_parser::data::get_packetdata. A complete example (doing much more than you probably need) of block handling can be found here

Note the pcap format is in fact not easy because of the many possible encapsulations and link-layers, the endianness, etc. This is why I am also working on pcap-analyzer.

chifflier commented 3 months ago

I tried writing a quick example, if your file is a legacy pcap file:

    let path = "assets/le-nflog.pcap";
    let content = fs::read(path).expect("could not read pcap file");
    let (rem, header) = parse_pcap_header(&content).expect("parsing failed");
    let mut i = rem;
    let mut num_blocks = 0;
    loop {
        match parse_pcap_frame(i) {
            Ok((rem, block)) => {
                // read block data (linktype is NFLOG)
                let res = get_packetdata(block.data, header.network, block.caplen as usize);
                let packetdata = res.expect("parsing data failed");
                match packetdata {
                    PacketData::L2(data) => todo!(),
                    PacketData::L3(ethertype, data) => todo!(),
                    PacketData::L4(datatype, data) => todo!(),
                    PacketData::Unsupported(_) => todo!(),
                }

                num_blocks += 1;
                i = rem;
            }
            Err(ErrMode::Incomplete(_)) => break,
            // Err(ErrMode(PcapError::Incomplete(_)) => break,
            Err(e) => panic!("Unexpected error: {:?}", e),
        }
    }

In the match arms, data is what you want. You might simplify some cases if you know you have only layer 3 data.

If your file is using format pcap-ng, you will need to adapt that code. The code in pcap-analyzer show how to abstract this and handle all cases.

spirrello commented 3 months ago

Excellent thx so much. I'll give this a try.