Table Of Contents
Table Of Contents

PCAP Recording

Goals

INET has the capability to record PCAP traces from simulations. These PCAP files have the same format as real-world PCAP traces, so that the same tools and techniques used to analyze real traffic can also be applied to simulated traffic. This means that popular tools like Wireshark and tcpdump can be leveraged in the context of simulations.

This demonstration includes a sample simulation that generates and records PCAP traces of TCP, UDP, and ICMP traffic, using various physical layer protocols such as Ethernet and 802.11.

INET version: 4.0

The model

To record PCAP traces in a node, a PcapRecorder module needs to be included in it. Pcap recorder modules can be easily included in hosts and routers by specifying their numPcapRecorders parameter (available in modules that extend LinkLayerNodeBase, such as StandardHost and derivatives, and router modules.)

The PCAP recorder module records packets sent to and from modules that are in the same host as the PCAP recorder module. It writes traces in a PCAP file, which has to be specified by the pcapFile parameter. This parameter acts as the main switch for recording, thus specifying this parameter enables packet capture. The PCAP recorder can write traces in the original or the next-generation PCAP file format, selected by the fileFormat parameter (pcap or pcapng).

The moduleNamePatterns parameter specifies which modules’ traffic should be recorded. It takes a space separated list of module names. For selecting a module vector, [*] can be used. The recorded modules are on the same level in the hierarchy as the PCAP recorder module. The default value for the moduleNamePatterns parameter is wlan[*] eth[*] ppp[*], so it records the most commonly present L2 interfaces. The dumpProtocols parameter is a filter and selects which protocols to include in the capture. It matches packets which are of the specified protocol type at the level of capture, but not the protocol type of encapsulated packets. The parameter takes protocol names registered in INET (see /inet/src/inet/common/Protocol.cc) The parameter’s default value is "ethernetmac ppp ieee80211mac".

By default, the PCAP recorder module records L2 frames, but setting the moduleNamePatterns to ipv4, for example, lets one record L3 frames (note that the parameter’s value is lowercase because it refers to the actual ipv4 module in the host, not the module type.)

Additionally, the packetFilter parameter can use an expression to filter packets. The expression is evaluated for all packets to a boolean value indicating a match. The expression can contain the packet’s fields (such as its name), contained chunks and their fields, protocol headers, etc. The default value is * that matches all packets, thus no packets are filtered. For more information on the packet filter, refer to the TODO section in the INET User’s Guide.

To summarize: the moduleNamePatterns parameter specifies which modules’ outputs should be captured. The pcapNetwork parameter sets the link-layer header type according to the captured module outputs, so PCAP programs can interpret the PCAP file correctly. The dumpProtocols parameter can narrow the set of recorded protocols at the level of capture. The packetFilter parameter can further narrow the set of captured packets.

The configuration

The example simulation for this showcase contains wired hosts, wireless hosts, and routers. The hosts are configured to generate TCP, UDP and ICMP traffic. The hosts connect to routers via Ethernet; the connection between the routers is PPP. The wireless hosts communicate via 802.11. The simulation can be run by choosing the PcapRecording configuration from the ini file. The simulation uses the following network:

../../../../_images/network2.png

The network contains two adhocHosts named host1 and host2, and two StandardHosts named ethHost1 and ethHost2. There are two Router modules (router1 and router2), which are connected by PPP. Each wired host is connected to one of the routers via Ethernet. The network also contains an Ipv4NetworkConfigurator, an Ieee80211ScalarRadioMedium, and an IntegratedMultiVisualizer module.

Traffic generation is set up the following way: host1 is configured to send a UDP stream to host2 (via 802.11), ethHost1 is configured to open a TCP connection to ethHost2, and send a 1Mbyte file (via Ethernet). Additionally, ethHost1 is configured to ping ethHost2.

We set up multiple PCAP recorder modules in various hosts in the network:

In host1, we’ll record 802.11 traffic on the wlan0 interface. We configure host1’s PCAP recorder to use the 802.11 link-layer headers:

*.host1.numPcapRecorders = 1
*.host1.pcapRecorder[*].pcapFile = "results/host1.pcap"

In host2, we’ll record only the ARP packets from the 802.11 traffic on wlan0. The link-layer header type is set to 802.11, and the packetFilter is set to record only to packets of ArpPacket class:

*.host2.numPcapRecorders = 1
*.host2.pcapRecorder[*].packetFilter = "*ArpPacket"

The packetFilter parameter’s value *ArpPacket matches the inet::ArpPacket class. There is an ARP request packet open in the packet inspector on the following image:

../../../../_images/arppacketclass.png

In ethHost1, we’ll record Ethernet traffic on the eth0 interface. We set the link-layer header type to ethernet:

*.ethHost1.numPcapRecorders = 1
*.ethHost1.pcapRecorder[*].pcapFile = "results/ethHost1.pcap"

There are two PCAP recorder modules in router1, with one of them recording Ethernet traffic on eth0 and the other PPP traffic on ppp0. The moduleNamePatters parameter needs to be set for both PCAP recorder modules, because router1 has two interfaces.

*.router1.numPcapRecorders = 2
*.router1.pcapRecorder[0].moduleNamePatterns = "ppp[*]"
*.router1.pcapRecorder[0].pcapFile = "results/router1.ppp.pcap"
*.router1.pcapRecorder[1].pcapFile = "results/router1.eth.pcap"
*.router1.pcapRecorder[1].moduleNamePatterns = "eth[*]"

In router2, we’ll record only packets carrying TCP data on the eth0 interface. router2 has two interfaces, so the moduleNamePatters parameter needs to be set. The link-layer header type is set to ethernet, and the packet data filter is set to match packets containing an Ipv4Header, and where the totalLengthField field’s value is 576 (the size of TCP data packets with IP encapsulation):

*.router2.numPcapRecorders = 1
*.router2.pcapRecorder[*].moduleNamePatterns = "eth[*]"
*.router2.pcapRecorder[*].pcapFile = "results/router2.tcpdata.pcap"
*.router2.pcapRecorder[*].packetFilter = expr(has(Ipv4Header) && Ipv4Header.totalLengthField == 576B)

In ethHost2, we’ll record traffic of the ipv4 module. The dumpProtocols parameter’s default is ethernetmac ppp ieee80211mac, so it has to be set to ipv4.

*.ethHost2.numPcapRecorders = 1
*.ethHost2.pcapRecorder[*].pcapFile = "results/ethHost2.ip.pcap"
*.ethHost2.pcapRecorder[*].moduleNamePatterns = "ipv4"
*.ethHost2.pcapRecorder[*].dumpProtocols = "ipv4"

By default, modules like Ipv4 and EthernetInterface don’t compute CRC and FCS frames, but assumes they are correct (“declared correct” mode.) To include the CRC and FCS values in the capture file, L2 and L3 modules need to be set to compute CRC and FCS:

**.crcMode = "computed"
**.fcsMode = "computed"

Note that these settings are required, otherwise an error is returned.

The alwaysFlush parameter controls whether to write packets to the PCAP file as they are recorded or after the simulation has concluded. It is false by default, but it’s set to true in all PCAP recorders to make sure there are recorded packets even if the simulation crashes:

**.pcapRecorder[*].alwaysFlush = true

Results

The following video shows the traffic in the network:

The following images show the same packets viewed in Qtenv’s packet mode inspector panel and the PCAP trace opened with Wireshark. Both display the same data about the same packet (with the same data, sequence number, CRC, etc. Click to zoom.)

TCP data, in ethHost1 (sent from ethHost1 to ethHost2):

../../../../_images/ethHost9.png

Ping request, in router1’s eth interface (sent from ethHost1 to router1):

../../../../_images/routerEth2_2.png

TCP ACK, in router1’s ppp interface (sent from ethHost1 to ethHost2):

../../../../_images/routerPPP3.png

UDP data packet, in host1’s wlan interface (sent from host1 to host2):

../../../../_images/wifi5.png

The following screenshot shows ethHost1.pcap opened with TCPDump:

../../../../_images/tcpdump.png

TCP data packet, in ethHost2, recorded at the IPv4 module (sent from ethHost1 to ethHost2):

../../../../_images/rawip.png

The following images are the PCAP traces from host2 and router2, where the set of recorded packets were narrowed with packetFilter.

The ARP packets from host2:

../../../../_images/arp.png

The TCP data packets from router2:

../../../../_images/tcpdata.png

Sources: omnetpp.ini, PcapRecordingShowcase.ned

Try It Yourself

If you already have INET and OMNeT++ installed, start the IDE by typing omnetpp, import the INET project into the IDE, then navigate to the inet/showcases/general/pcaprecording folder in the Project Explorer. There, you can view and edit the showcase files, run simulations, and analyze results.

Otherwise, there is an easy way to install INET and OMNeT++ using opp_env, and run the simulation interactively. Ensure that opp_env is installed on your system, then execute:

$ opp_env run inet-4.0 --init -w inet-workspace --install --chdir \
   -c 'cd inet-4.0.*/showcases/general/pcaprecording && inet'

This command creates an inet-workspace directory, installs the appropriate versions of INET and OMNeT++ within it, and launches the inet command in the showcase directory for interactive simulation.

Alternatively, for a more hands-on experience, you can first set up the workspace and then open an interactive shell:

$ opp_env install --init -w inet-workspace inet-4.0
$ cd inet-workspace
$ opp_env shell

Inside the shell, start the IDE by typing omnetpp, import the INET project, then start exploring.

Discussion

Use this page in the GitHub issue tracker for commenting on this showcase.