NetPacket provides a base class for a cluster of modules related to decoding and encoding of network protocol packets. Each NetPacket descendant module knows how to encode and decode packets for the network protocol it implements. Protocols that NetPacket can encode/decode include IPv4, TCP, UDP, ICMP, Ethernet, and ARP.

I've written three additional modules for NetPacket that allow the encoding/decoding of IPv6, ICMPv6, and OpenBSD's Packet Filter binary log files. I've also made numerous changes to existing modules, including fixing spelling mistakes, bug fixes, and documentation enhancements.

If you're using OpenBSD, you can install the p5-NetPacket port/package which already contains the patches outlined below.

IPv6 Modules

The IPv6 modules allow for the encoding/decoding of IPv6 and ICMPv6 packets. These modules, like the modules that make up the NetPacket distribution, can be used to analyze tcpdump or Wireshark packet captures that contain IPv6/ICMPv6 packets.

Some example code might look like this:

#!/usr/bin/perl -w
use strict;
use Net::PcapUtils;
use NetPacket::Ethernet qw(:strip);
use NetPacket::IPv6;

sub process_pkt {
  my ($user, $hdr, $pkt) = @_;

  my $ip6_obj = NetPacket::IPv6->decode(eth_strip($pkt));
  print("$ip6_obj->{src_ip} -> $ip6_obj->{dest_ip} ");
  print("$ip6_obj->{nxt}\n");
}

Net::PcapUtils::loop(&process_pkt, FILTER => 'ip6');

This code snippet starts a packet capture and looks for IPv6 packets (the FILTER keyword). Each packet seen is passed to the process_pkt function where the source IP, destination IP, and the "next header" value are output. The output would look similar to this:

2001:618:4cfa:a00:0:0:1:a00 -> 2001:b40d:44:62:0:0:0:276 58

The perlpod documentation that comes with the modules explains all of the data fields that get decoded as well as the object methods. Use the perldoc NetPacket::IPv6 and perldoc NetPacket::ICMPv6 commands to view the documentation.

OpenBSD Packet Filter Module

OpenBSD's Packet Filter firewall software stores its log files as a libpcap packet dump. This is a binary file format and cannot be read by humans. Additional software is needed to parse and format the log files for analysis and viewing. The PFLog NetPacket module that I've written allows for decoding of this binary data.

Some example code might look like this:

#!/usr/bin/perl
use strict;
use Net::Pcap;
use NetPacket;
use NetPacket::IP;
use NetPacket::PFLog;

sub analyze_dump {
  my ($user_data, $header, $packet) = @_;
  my $pflog = NetPacket::PFLog->decode($packet);
  my $ip = NetPacket::IP->decode($pflog->{data});
  print "$pflog->{action} $pflog->{dir} on $pflog->{ifname}";
  print " $ip->{src_ip} -> $ip->{dest_ip}\n";
}

my ($pcap_t, $pcaperr);
$pcap_t = Net::Pcap::open_offline("/var/log/pflog", \$pcaperr);
Net::Pcap::loop($pcap_t, -1, &analyze_dump, "");
Net::Pcap::close($pcap_t);

This code snippet opens the PF log file /var/log/pflog, iterates through each packet in the log and prints the action taken on the packet (pass or block), the packet direction (in or out), the interface name, and the source and destination IP address. The output would look similar to this:

pass in on em0 172.16.0.2 -> 172.16.0.3

The perlpod documentation that comes with the module explains all of the data fields that get decoded as well as the PFLog object methods. Use the perldoc NetPacket::PFLog command to view the documentation.

Download

The code is distributed as a patch to the NetPacket distribution.

Apply the patch:

patch < netpacket-1.4.4.diff

Build NetPacket as per the INSTALL file.

If you're an OpenBSD user, then you can simply install the net/p5-NetPacket port and be done. The patches are installed automatically (although the port may not always have the most up-to-date version of the patch).