seladb / PcapPlusPlus

PcapPlusPlus is a multiplatform C++ library for capturing, parsing and crafting of network packets. It is designed to be efficient, powerful and easy to use. It provides C++ wrappers for the most popular packet processing engines such as libpcap, Npcap, WinPcap, DPDK, AF_XDP and PF_RING.
https://pcapplusplus.github.io/
The Unlicense
2.75k stars 674 forks source link

UDP Source/Destination ports not reading correctly #89

Closed mjmjelde closed 6 years ago

mjmjelde commented 6 years ago

Howdy,

I am currently trying to get the source and destination ports of some UDP packets, however it seems like they are not being read correctly.

A sample file that I am testing on is the tpncp_udp.pcap file from the wireshark samples page, found here: https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=tpncp_udp.pcap

The first packet in this file is from 10.4.2.44:2428 and is going to destination 10.4.96.100:2424 according to wireshark. However, when I use the following code, the source port shows up as 31753 and the destination port is 30729. Is there something I am doing wrong?

#include <IPv4Layer.h>
#include <Packet.h>
#include <PcapFileDevice.h>
#include <UdpLayer.h>

int main(int argc, char* argv[])
{

    // open a pcap file for reading
    pcpp::PcapFileReaderDevice reader("d:\\tpncp_udp.pcap");
    if (!reader.open())
    {
        printf("Error opening the pcap file\n");
        return 1;
    }

    // read the first (and only) packet from the file
    pcpp::RawPacket rawPacket;
    if (!reader.getNextPacket(rawPacket))
    {
        printf("Couldn't read the first packet in the file\n");
        return 1;
    }

    // parse the raw packet into a parsed packet
    pcpp::Packet parsedPacket(&rawPacket);

    // verify the packet is IPv4
    if (parsedPacket.isPacketOfType(pcpp::IPv4))
    {
        // extract source and dest IPs
        pcpp::IPv4Address srcIP = parsedPacket.getLayerOfType<pcpp::IPv4Layer>()->getSrcIpAddress();
        pcpp::IPv4Address destIP = parsedPacket.getLayerOfType<pcpp::IPv4Layer>()->getDstIpAddress();

        // print source and dest IPs
        printf("Source IP is '%s'; Dest IP is '%s'\n", srcIP.toString().c_str(), destIP.toString().c_str());

        pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType<pcpp::UdpLayer>();
        printf("Source port is '%d'; Dest Port is '%d'\n", udpLayer->getUdpHeader()->portSrc, udpLayer->getUdpHeader()->portDst);
    }

    // close the file
    reader.close();

    return 0;
}
seladb commented 6 years ago

You need to convert the port value from network to host order using ntohs():

printf("Source port is '%d'; Dest Port is '%d'\n", ntohs(udpLayer->getUdpHeader()->portSrc), ntohs(udpLayer->getUdpHeader()->portDst));

ntohs(31753) => 2428 ntohs(30729) => 2424

You can also take a look at the following tutorial to understand more: http://seladb.github.io/PcapPlusPlus-Doc/tutorial_packet_parsing.html

seladb commented 6 years ago

Did it solve the issue?

mjmjelde commented 6 years ago

Hey sorry I meant to respond yesterday and forgot. Yes this resolved my issue. Thanks! I will go ahead and close this ticket