diff -pruN NetPacket-0.41.1.orig/MANIFEST NetPacket-0.41.1/MANIFEST
--- NetPacket-0.41.1.orig/MANIFEST	Tue Jan  6 14:23:41 2009
+++ NetPacket-0.41.1/MANIFEST	Sun Mar  1 12:04:47 2009
@@ -10,6 +10,9 @@ lib/NetPacket/IGMP.pm
 lib/NetPacket/IP.pm
 lib/NetPacket/UDP.pm
 lib/NetPacket/TCP.pm
+lib/NetPacket/IPv6.pm
+lib/NetPacket/ICMPv6.pm
+lib/NetPacket/PFLog.pm
 t/ip_encode.t
 Changes
 t/ip_trailing.t
diff -pruN NetPacket-0.41.1.orig/lib/NetPacket/ICMP.pm NetPacket-0.41.1/lib/NetPacket/ICMP.pm
--- NetPacket-0.41.1.orig/lib/NetPacket/ICMP.pm	Tue Jan  6 14:23:41 2009
+++ NetPacket-0.41.1/lib/NetPacket/ICMP.pm	Sun Mar  1 12:03:23 2009
@@ -262,7 +262,7 @@ none
 
 =item exportable
 
-Icmp message types: 
+ICMP message types: 
     ICMP_ECHOREPLY ICMP_UNREACH ICMP_SOURCEQUENCH
     ICMP_REDIRECT ICMP_ECHO ICMP_ROUTERADVERT
     ICMP_ROUTERSOLICIT ICMP_TIMXCEED ICMP_PARAMPROB
@@ -276,6 +276,14 @@ The following tags group together related exportable i
 
 =over
 
+=item C<:types>
+
+  ICMP_ECHOREPLY ICMP_UNREACH ICMP_SOURCEQUENCH
+  ICMP_REDIRECT ICMP_ECHO ICMP_ROUTERADVERT
+  ICMP_ROUTERSOLICIT ICMP_TIMXCEED ICMP_PARAMPROB
+  ICMP_TSTAMP ICMP_TSTAMPREPLY ICMP_IREQ 
+  ICMP_IREQREPLY ICMP_MASKREQ ICMP_MASKREPLY
+
 =item C<:strip>
 
 Import the strip function C<icmp_strip>.
@@ -290,13 +298,35 @@ All the above exportable items.
 
 =head1 EXAMPLE
 
+The following example prints the ICMP type, code, and checksum 
+fields.
+
+  #!/usr/bin/perl -w
+
+  use strict;
+  use Net::PcapUtils;
+  use NetPacket::Ethernet qw(:strip);
+  use NetPacket::IP qw(:strip);
+  use NetPacket::ICMP;
+
+  sub process_pkt {
+      my ($user, $hdr, $pkt) = @_;
+
+      my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
+      my $icmp_obj = NetPacket::ICMP->decode(ip_strip($ip_obj));
+
+      print("Type: $icmp_obj->{type}\n");
+      print("Code: $icmp_obj->{code}\n");
+      print("Checksum: $icmp_obj->{cksum}\n\n");
+  }
+
+  Net::PcapUtils::loop(\&process_pkt, FILTER => 'icmp');
+
 =head1 TODO
 
 =over
 
 =item Create constants
-
-=item Write example
 
 =back
 
diff -pruN NetPacket-0.41.1.orig/lib/NetPacket/ICMPv6.pm NetPacket-0.41.1/lib/NetPacket/ICMPv6.pm
--- NetPacket-0.41.1.orig/lib/NetPacket/ICMPv6.pm	Wed Dec 31 17:00:00 1969
+++ NetPacket-0.41.1/lib/NetPacket/ICMPv6.pm	Sun Mar  1 13:13:00 2009
@@ -0,0 +1,398 @@
+#
+# ICMPv6.pm
+# NetPacket::ICMPv6
+#
+# Decode Internet Control Message Protocol v6 packet header.
+#
+# References:
+# RFC2463 - ICMPv6 Specification
+#
+# Copyright (c) 2003-2009 Joel Knight <knight.joel@gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+# $jwk: ICMPv6.pm,v 1.16 2009/03/01 20:12:46 jwk Exp $
+
+package NetPacket::ICMPv6;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+use NetPacket;
+
+my $myclass;
+BEGIN {
+    $myclass = __PACKAGE__;
+    $VERSION = "0.02";
+}
+sub Version () { "$myclass v$VERSION" }
+
+BEGIN {
+    @ISA = qw(Exporter NetPacket);
+
+    @EXPORT = qw( );
+
+    @EXPORT_OK = qw(
+		icmpv6_strip
+		ICMPV6_DST_UNREACH
+		ICMPV6_PACKET_TOO_BIG
+		ICMPV6_TIME_EXCEEDED
+		ICMPV6_PARAM_PROB
+		ICMPV6_ECHO_REQUEST
+		ICMPV6_ECHO_REPLY
+	);
+
+    %EXPORT_TAGS = (
+    ALL         => [@EXPORT, @EXPORT_OK],
+    types       => [qw(
+		ICMPV6_DST_UNREACH
+		ICMPV6_PACKET_TOO_BIG
+		ICMPV6_TIME_EXCEEDED
+		ICMPV6_PARAM_PROB
+		ICMPV6_ECHO_REQUEST
+		ICMPV6_ECHO_REPLY
+					)],
+    strip       => [qw(icmpv6_strip)],
+);
+
+}
+
+use NetPacket::IPv6;
+
+# icmp6 packet types
+use constant ICMPV6_DST_UNREACH		=> 1;
+use constant ICMPV6_PACKET_TOO_BIG	=> 2;
+use constant ICMPV6_TIME_EXCEEDED	=> 3;
+use constant ICMPV6_PARAM_PROB		=> 4;
+use constant ICMPV6_ECHO_REQUEST	=> 128;
+use constant ICMPV6_ECHO_REPLY		=> 129;
+
+# calculate icmp6 checksum; note that parts of the outer ipv6
+# packet are needed for the calculation
+sub checksum {
+	my $self = shift;
+	my $ip6 = $_[0];
+
+	my @src_ip = NetPacket::IPv6::hexstr_to_int($ip6->{src_ip});
+	my @dst_ip = NetPacket::IPv6::hexstr_to_int($ip6->{dest_ip});
+
+	my $extra = $self->_get_extra_field;
+
+	# XXX will there ever be a header between the ip6 and icmp6 headers?
+	# if so, using ip6->{plen} here is wrong; the length in the pseudo
+	# header is the length of the icmp6 packet only; RFC2460 8.1
+	my $hdr = pack('NNNNNNNNNNCCnNa*', @src_ip[0..3], @dst_ip[0..3], 
+		$ip6->{plen}, $ip6->{nxt}, $self->{type}, $self->{code},
+		0, $extra, $self->{data});
+
+	return NetPacket::htons(NetPacket::in_cksum($hdr));
+}
+
+# decode icmpv6 header, return a NetPacket::ICMPv6 object
+sub decode {
+	my $class = shift;
+	my ($pkt, $parent) = @_;
+	my $self = {};
+
+	# Class fields
+
+	$self->{_parent} = $parent;
+	$self->{_frame} = $pkt;
+	
+	# Decode packet
+
+	if (defined $pkt) {
+		($self->{type}, $self->{code}, $self->{cksum}, $self->{data})
+			= unpack('CCna*', $pkt);
+
+		# based on the icmp6 type, decode the rest of the packet
+		# XXX changes here must match _get_extra_field().
+		if ($self->{type} == ICMPV6_ECHO_REQUEST || 
+				$self->{type} == ICMPV6_ECHO_REPLY) {
+			($self->{id}, $self->{seq}, $self->{data})
+				= unpack('nna*', $self->{data});
+		} elsif ($self->{type} == ICMPV6_DST_UNREACH ||
+				$self->{type} == ICMPV6_TIME_EXCEEDED) {
+			($self->{unused}, $self->{data}) 
+				= unpack('Na*', $self->{data});
+		} elsif ($self->{type} == ICMPV6_PACKET_TOO_BIG) {
+			($self->{mtu}, $self->{data}) 
+				= unpack('Na*', $self->{data});
+		} elsif ($self->{type} == ICMPV6_PARAM_PROB) {
+			($self->{ptr}, $self->{data}) 
+				= unpack('Na*', $self->{data});
+		}
+	}
+
+	bless ($self, $class);
+	return $self;
+}
+
+undef &icmpv6_strip;           # Create alias
+*icmpv6_strip = \&strip;
+
+# return the data portion of an ipv6 packet
+sub strip {
+	my ($pkt) = $_[0];
+
+	my $icmpv6_obj = NetPacket::ICMPv6->decode($pkt);
+	return $icmpv6_obj->{data};
+}   
+
+# reverse the decoding process and return the raw, encoded packet
+sub encode {
+	my $class = shift;
+	my $self = shift;
+	my $ip6 = $_[0];
+
+	my $cksum = $self->checksum($ip6);
+	my $extra = $self->_get_extra_field;
+
+	my $packet = pack('CCnNa*', $self->{type}, $self->{code},
+		$cksum, $extra, $self->{data});
+
+	return($packet);
+}
+
+# based on the icmp6 type, return the data from the type-dependant
+# header field.
+# XXX changes here must match type-dependent code in decode().
+sub _get_extra_field {
+	my $self = shift;
+
+	my $f;
+	if ($self->{type} == ICMPV6_ECHO_REQUEST ||
+			$self->{type} == ICMPV6_ECHO_REPLY) {
+		$f = (($self->{id} << 16) & 0xffff0000) | $self->{seq};
+	} elsif ($self->{type} == ICMPV6_DST_UNREACH ||
+			$self->{type} == ICMPV6_TIME_EXCEEDED) {
+		$f = $self->{unused};
+	} elsif ($self->{type} == ICMPV6_PACKET_TOO_BIG) {
+		$f = $self->{mtu};
+	} elsif ($self->{type} == ICMPV6_PARAM_PROB) {
+		$f = $self->{ptr};
+	}
+
+	return $f;
+}
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+C<NetPacket::ICMPv6> - Assemble and disassemble ICMPv6 (Internet Control
+Message Protocol Version 6) packets. 
+
+=head1 SYNOPSIS
+
+  use NetPacket::ICMPv6;
+
+  $icmp6_obj = NetPacket::ICMPv6->decode($raw_pkt);
+  $icmp6_pkt = NetPacket::ICMPv6->encode($ip6_obj);
+  $icmp6_data = NetPacket::ICMPv6::strip($raw_pkt);
+  $cksum = $icmp6_obj->checksum($ip6_obj);
+
+=head1 DESCRIPTION
+
+C<NetPacket::ICMPv6> provides a set of routines for assembling and
+disassembling ICMPv6 (Internet Control Message Protocol Version 6) packets. 
+
+=head2 Methods
+
+=over
+
+=item C<NetPacket::ICMPv6-E<gt>decode([RAW PACKET])>
+
+Decode the raw packet data given and return an object containing
+instance data.  This method will quite happily decode garbage input.
+It is the responsibility of the programmer to ensure valid packet data
+is passed to this method.
+
+=item C<NetPacket::ICMPv6-E<gt>encode($ip6_obj)>
+
+Return an ICMPv6 packet encoded with the instance data specified. The
+C<NetPacket::IPv6> object that the ICMPv6 packet was encapsulated
+in must be passed to encode() because some of the IPv6 header fields
+are used in the ICMPv6 checksum calculation.
+
+=item C<NetPacket::ICMPv6-E<gt>checksum($ip6_obj)>
+
+Calculate the ICMPv6 checksum based on the instance data of the 
+C<NetPacket::ICMPv6> object. The C<NetPacket::IPv6> object that the 
+ICMPv6 packet was/will be encapsulated in must be specified as some
+of the IPv6 header fields are used in the ICMPv6 calculation.
+
+=back
+
+=head2 Functions
+
+=over
+
+=item C<NetPacket::ICMPv6::strip([RAW PACKET])>
+
+Return the encapsulated data (or payload) contained in the ICMPv6
+packet.
+
+=back
+
+=head2 Instance data
+
+The instance data for the C<NetPacket::ICMPv6> object consists of
+the following fields.
+
+=over
+
+=item type
+
+The ICMPv6 message type of this packet.
+
+=item code
+
+The ICMPv6 message code of this packet.
+
+=item cksum
+
+The checksum for this packet.
+
+=item data
+
+The encapsulated data (payload) for this packet.
+
+=back
+
+=head2 Type-Specific Instance Data
+
+=over
+
+=item id
+
+Identification number used to match Echo Requests with Echo Replies.
+(Echo Request, Echo Reply)
+
+=item seq
+
+Sequence number used to match Echo Requests with Echo Replies. (Echo
+Request, Echo Reply)
+
+=item mtu
+
+The Maximum Transmission Unit of the next-hop link. (Packet Too Big)
+
+=item ptr
+
+Problem pointer. Identifies the location in the original packet where
+the problem was. (Parameter Problem)
+
+=item unused
+
+These ICMPv6 types contain an unused header field: Destination 
+Unreachable, Time Exceeded.
+
+=back
+
+=head2 Exports
+
+=over
+
+=item default
+
+none
+
+=item exportable
+
+ICMPv6 message types: 
+
+  ICMPV6_DST_UNREACH ICMPV6_PACKET_TOO_BIG
+  ICMPV6_TIME_EXCEEDED ICMPV6_PARAM_PROB
+  ICMPV6_ECHO_REQUEST ICMPV6_ECHO_REPLY
+
+Strip function:
+
+  icmpv6_strip
+
+=item tags
+
+The following tags group together related exportable items.
+
+=over
+
+=item C<:strip>
+
+Import the strip function C<icmpv6_strip>.
+
+=item C<:types>
+
+Import the above ICMPv6 message types.
+
+=item C<:ALL>
+
+All the above exportable items.
+
+=back
+
+=back
+
+=head1 EXAMPLE
+
+The following example prints the ICMPv6 type, code, and checksum 
+fields.
+
+  #!/usr/bin/perl -w
+
+  use strict;
+  use Net::PcapUtils;
+  use NetPacket::Ethernet qw(:strip);
+  use NetPacket::IPv6 qw(:strip);
+  use NetPacket::ICMPv6;
+
+  sub process_pkt {
+      my ($user, $hdr, $pkt) = @_;
+
+      my $ip6_obj = NetPacket::IPv6->decode(eth_strip($pkt));
+      my $icmp6_obj = NetPacket::ICMPv6->decode(ipv6_strip($ip6_obj));
+
+      print("Type: $icmp6_obj->{type}\n");
+      print("Code: $icmp6_obj->{code}\n");
+      print("Checksum: $icmp6_obj->{cksum}\n\n");
+  }
+
+  Net::PcapUtils::loop(\&process_pkt, FILTER => 'icmp6');
+
+=head1 TODO
+
+Nothing at this time.
+
+=head1 COPYRIGHT
+
+Copyright (c) 2003-2009 Joel Knight <knight.joel@gmail.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+=head1 AUTHOR
+
+Joel Knight E<lt>knight.joel@gmail.comE<gt>
+
+=cut
diff -pruN NetPacket-0.41.1.orig/lib/NetPacket/IP.pm NetPacket-0.41.1/lib/NetPacket/IP.pm
--- NetPacket-0.41.1.orig/lib/NetPacket/IP.pm	Tue Jan  6 14:23:41 2009
+++ NetPacket-0.41.1/lib/NetPacket/IP.pm	Sun Mar  1 12:21:12 2009
@@ -273,7 +273,7 @@ is passed to this method.
 
 Return an IP packet encoded with the instance data specified. This
 will infer the total length of the packet automatically from the 
-payload lenth and also adjust the checksum.
+payload length and also adjust the checksum.
 
 =back
 
diff -pruN NetPacket-0.41.1.orig/lib/NetPacket/IPv6.pm NetPacket-0.41.1/lib/NetPacket/IPv6.pm
--- NetPacket-0.41.1.orig/lib/NetPacket/IPv6.pm	Wed Dec 31 17:00:00 1969
+++ NetPacket-0.41.1/lib/NetPacket/IPv6.pm	Sun Mar  1 12:12:36 2009
@@ -0,0 +1,378 @@
+#
+# IPv6.pm
+# NetPacket::IPv6
+#
+# Decode Internet Protocol v6 packet header.
+#
+# References:
+# RFC2460 - IPv6 Specification
+#
+# Copyright (c) 2003-2009 Joel Knight <knight.joel@gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+# $jwk: IPv6.pm,v 1.15 2009/03/01 19:12:03 jwk Exp $
+
+package NetPacket::IPv6;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+use NetPacket;
+
+my $myclass;
+BEGIN {
+    $myclass = __PACKAGE__;
+    $VERSION = "0.02";
+}
+sub Version () { "$myclass v$VERSION" }
+
+BEGIN {
+    @ISA = qw(Exporter NetPacket);
+
+    @EXPORT = qw( );
+
+    @EXPORT_OK = qw(
+		ipv6_strip
+		IP_PROTO_IPV6 IP_PROTO_ICMPV6
+		IP_VERSION_IPv6 IPV6_VERSION
+		IPV6_MAXPACKET
+    );
+
+    %EXPORT_TAGS = (
+    ALL         => [@EXPORT, @EXPORT_OK],
+    protos      => [qw(IP_PROTO_IPV6 IP_PROTO_ICMPV6)],
+    versions    => [qw(IP_VERSION_IPv6 IPV6_VERSION)],
+    strip       => [qw(ipv6_strip)],
+);
+
+}
+
+# possible 'next-header' values
+use constant IP_PROTO_IPV6   => 41;		# IPv6
+use constant IP_PROTO_ICMPV6 => 58;		# ICMPv6
+
+use constant IP_VERSION_IPv6 => 6;
+use constant IPV6_VERSION => IP_VERSION_IPv6;
+
+# size of the ipv6 header in bytes
+use constant IPV6_HDRLEN => 40;
+
+# maximum ipv6 packet size in bytes
+use constant IPV6_MAXPACKET => 65535 + IPV6_HDRLEN;
+
+# convert 4, 32-bit integers to a hex string with every two bytes
+# separated by a colon
+sub int_to_hexstr {
+	my @int = @_;
+
+	my @n;
+	foreach my $i (0..3) {
+		push @n, (($int[$i] & 0xffff0000) >> 16);
+		push @n, ($int[$i] & 0x0000ffff);
+	}
+
+	return sprintf("%x:%x:%x:%x:%x:%x:%x:%x", @n[0..7]);
+}
+
+# convert a string of 8, 16-bit hex numbers to 4, 32-bit integers
+sub hexstr_to_int {
+	my @n = split m/:/, $_[0];
+
+	my @int;
+	foreach my $i (0,2,4,6) {
+		my $h = hex $n[$i];
+		my $l = hex $n[$i+1];
+		my $int;
+		$int = $l & 0x0000ffff;
+		$int = $int | (($h << 16 ) & 0xffff0000);
+		push @int, $int;
+	}
+	
+	return @int;
+}
+
+# decode ipv6 header, return a NetPacket::IPv6 object
+sub decode {
+	my $class = shift;
+	my ($pkt, $parent, @rest) = @_;
+	my $self = {};
+
+	# Class fields
+
+	$self->{_parent} = $parent;
+	$self->{_frame} = $pkt;
+
+	# Decode packet
+
+	if (defined $pkt) {
+		my ($tmp, @src, @dst);
+		
+		($tmp, $self->{plen}, $self->{nxt}, $self->{hlim}, @src[0..3], 
+			@dst[0..3], $self->{data}) = unpack('NncCNNNNNNNNa*', $pkt);
+
+		$self->{ver} = ($tmp & 0xf0000000) >> 28;
+		$self->{class} = ($tmp & 0x0ff00000) >> 20;
+		$self->{flow} = ($tmp & 0x000fffff);
+
+		$self->{src_ip} = int_to_hexstr(@src);
+		$self->{dest_ip} = int_to_hexstr(@dst);
+	}
+
+	bless ($self, $class);
+	return $self;
+}
+
+undef &ipv6_strip;           # Create alias
+*ipv6_strip = \&strip;
+
+# return the data portion of an ipv6 packet
+sub strip {
+	my ($pkt, @rest) = @_;
+
+	my $ipv6_obj = NetPacket::IPv6->decode($pkt);
+	return $ipv6_obj->{data};
+}   
+
+# reverse the decoding process and return the raw, encoded packet.
+# take into account any member data that may have changed.
+sub encode {
+	my $class = shift;
+	my $self = shift;
+
+	$self->{plen} = length $self->{data};
+
+	my $tmp;
+	$tmp = $self->{flow} & 0x000fffff;
+	$tmp = $tmp | (($self->{class} << 20) & 0x0ff00000);
+	$tmp = $tmp | (($self->{ver} << 28) & 0xf0000000);
+
+	my @src = hexstr_to_int($self->{src_ip});
+	my @dst = hexstr_to_int($self->{dest_ip});
+
+	my $packet = pack('NncCNNNNNNNNa*', $tmp, $self->{plen},
+		$self->{nxt}, $self->{hlim}, @src[0..3], @dst[0..3],
+		$self->{data});
+
+	return($packet);
+}
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+C<NetPacket::IPv6> - Assembling and disassembling IPv6 (Internet
+Protocol Version 6) packets.
+
+=head1 SYNOPSIS
+
+  use NetPacket::IPv6;
+
+  $ip6_obj = NetPacket::IPv6->decode($raw_pkt);
+  $ip6_pkt = NetPacket::IPv6->encode();
+  $ip6_data = NetPacket::IPv6::strip($raw_pkt);
+
+=head1 DESCRIPTION
+
+C<NetPacket::IPv6> provides a set of routines for assembling and
+disassembling IPv6 (Internet Protocol Version 6) packets.  
+
+=head2 Methods
+
+=over
+
+=item C<NetPacket::IPv6-E<gt>decode([RAW PACKET])>
+
+Decode the raw packet data given and return an object containing
+instance data.  This method will quite happily decode garbage input. It
+is the responsibility of the programmer to ensure valid packet data is
+passed to this method.
+
+=item C<NetPacket::IPv6-E<gt>encode()>
+
+Return an IPv6 packet encoded with the instance data specified. This
+will infer the packet length automatically from the payload length.
+
+=back
+
+=head2 Functions
+
+=over
+
+=item C<NetPacket::IPv6::strip([RAW PACKET])>
+
+Return the encapsulated data (or payload) contained in the IPv6
+packet.  This data is suitable to be used as input for other
+C<NetPacket::*> modules.
+
+This function is equivalent to creating an object using the
+C<decode()> constructor and returning the C<data> field of that
+object.
+
+=back
+
+=head2 Instance data
+
+The instance data for the C<NetPacket::IPv6> object consists of
+the following fields.
+
+=over
+
+=item ver
+
+The IPv6 version number of this packet. This must always be 6.
+
+=item class
+
+The IPv6 traffic class.
+
+=item flow
+
+The IPv6 flow label.
+
+=item plen
+
+The payload length. This is the length of the payload (data); it does
+not include the length of the packet header.
+
+=item nxt
+
+The next header. This field identifies the type of header that follows
+the IPv6 header. It uses the same values as the IPv4 C<protocol> header.
+
+=item hlim
+
+The hop limit. Each router that handles the packet will decrement this
+field by 1. Once the field reaches 0, the packet is discarded. Similar
+to the C<TTL> field in the IPv4 header.
+
+=item src_ip
+
+The source IPv6 address. The address is expressed as a colon-separated
+hex string. Leading zeros within the hex numbers are removed.
+
+=item dest_ip
+
+The destination IPv6 address. The address is expressed as a
+colon-separated hex string. Leading zeros within the hex numbers are
+removed.
+
+=item data
+
+The encapsulated data (payload).
+
+=back
+
+=head2 Exports
+
+=over
+
+=item default
+
+none
+
+=item exportable
+
+Protocols:
+
+  IP_PROTO_IPV6 IP_PROTO_ICMPV6 
+
+IPv6 version number:
+
+  IP_VERSION_IPv6 IPV6_VERSION
+
+Maximum IPv6 packet size:
+
+  IPV6_MAXPACKET 
+
+Strip function:
+
+  ipv6_strip
+
+=item tags
+
+The following tags can be used to export certain items:
+
+=over
+
+=item C<:protos>
+
+IP_PROTO_IPV6 IP_PROTO_ICMPV6
+
+=item C<:versions>
+
+IP_VERSION_IPv6 IPV6_VERSION
+
+=item C<:strip>
+
+The function C<ipv6_strip>
+
+=item C<:ALL>
+
+All the above exportable items
+
+=back
+
+=back
+
+=head1 EXAMPLE
+
+The following prints the source and destination IPv6 address along 
+with the value of the C<next header> field.
+
+  #!/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');
+
+=head1 TODO
+
+Nothing at this time.
+
+=head1 COPYRIGHT
+
+Copyright (c) 2003, 2004 Joel Knight <knight.joel@gmail.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+=head1 AUTHOR
+
+Joel Knight E<lt>knight.joel@gmail.comE<gt>
+
+=cut
+
diff -pruN NetPacket-0.41.1.orig/lib/NetPacket/PFLog.pm NetPacket-0.41.1/lib/NetPacket/PFLog.pm
--- NetPacket-0.41.1.orig/lib/NetPacket/PFLog.pm	Wed Dec 31 17:00:00 1969
+++ NetPacket-0.41.1/lib/NetPacket/PFLog.pm	Sun Mar  1 17:24:58 2009
@@ -0,0 +1,394 @@
+#
+# PFLog.pm
+# NetPacket::PFLog
+#
+# Decodes OpenBSD's pflog(4) packets
+#
+# Copyright (c) 2003-2009 Joel Knight <knight.joel@gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+# $jwk: PFLog.pm,v 1.33 2009/03/02 00:24:54 jwk Exp $
+
+package NetPacket::PFLog;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+use NetPacket;
+use Socket;
+
+my $myclass;
+BEGIN {
+	$myclass = __PACKAGE__;
+	$VERSION = "0.02";
+}
+sub Version () { "$myclass v$VERSION" }
+
+BEGIN {
+	@ISA = qw(Exporter NetPacket);
+
+	@EXPORT = qw(
+	);
+
+	@EXPORT_OK = qw(
+		pflog_strip
+		DLT_PFLOG
+		PFLOG_HDRLEN
+	);
+
+	%EXPORT_TAGS = (
+		ALL         => [@EXPORT, @EXPORT_OK],
+		strip       => [qw(pflog_strip)],
+		DLT			=> [qw(DLT_PFLOG)],
+	);
+}
+
+#  data link type for pflog in the pcap dump
+use constant DLT_PFLOG => 117;
+
+#  maximum size of the header (in bytes) in the pcap dump
+use constant PFLOG_HDRLEN => 64;
+
+#  packet filter constants (src/sys/net/pfvar.h)
+my %PF_DIR = (
+	1 => "in",
+	2 => "out"
+);
+my %PF_ACTION = (
+	0 => "pass",
+	1 => "block",
+	2 => "scrub"
+);
+my %PF_REASON = (
+	0 => "match",
+	1 => "bad-offset",
+	2 => "fragment",
+	3 => "short",
+	4 => "normalize",
+	5 => "memory",
+	6 => "bad-timestamp",
+	7 => "congestion",
+	8 => "ip-options",
+	9 => "proto-cksum",
+	10 => "state-mismatch",
+	11 => "state-insert",
+	12 => "state-limit",
+	13 => "src-limit",
+	14 => "syn-proxy"
+);
+
+#  decode(packet, parent_packet, additional_data)
+#  create a new NetPacket::PFLog object. decode the pflog header
+#  from 'packet' and assign each field to the object.
+#  return the NetPacket::PFLog object.
+sub decode {
+	my $class = shift;
+	my ($pkt, $parent, @rest) = @_;
+	my $self = {};
+
+	$self->{_parent} = $parent;
+	$self->{_frame} = $pkt;
+
+	# based on pfloghdr struct in:
+	# [OpenBSD]/src/sys/net/if_pflog.h r1.14
+	if (defined $pkt) {
+		my ($len, $af, $action, $reason, $ifname, $ruleset, $rulenr, 
+			$subrulenr, $uid, $pid, $rule_uid, $rule_pid, $dir,
+			$pad, $data) =
+			unpack("CCCCa16a16NNLlLlCa3a*", $pkt);
+	
+		#  strip trailing NULs
+		$ifname =~ s/\W//g;
+		$ruleset =~ s/\W//g;
+
+		$self->{len} = $len;
+		$self->{af} = $af;
+		$self->{action} = $PF_ACTION{$action};
+		$self->{reason} = $PF_REASON{$reason};
+		$self->{ifname} = $ifname;
+		$self->{ruleset} = $ruleset;
+		$self->{rulenr} = $rulenr;
+		$self->{subrulenr} = $subrulenr;
+		$self->{uid} = $uid;
+		$self->{pid} = $pid;
+		$self->{rule_uid} = $rule_uid;
+		$self->{rule_pid} = $rule_pid;
+		$self->{dir} = $PF_DIR{$dir};
+		$self->{pad} = $pad;
+
+		$self->{data} = $data;
+	}
+
+	bless ($self, $class);
+	return $self;
+}
+
+# make an alias
+undef &pflog_strip;
+*pflog_strip = \&strip;
+
+# strip header from packet and return the data contained in it
+sub strip {
+	my ($pkt, @rest) = @_;
+
+	my $pflog_obj = NetPacket::PFLog->decode($pkt);
+	return $pflog_obj->{data};
+}   
+
+#  encode(ip_pkt)
+#  re-encapsulate an already decapsulated pflog packet
+sub encode {
+	my $class = shift;
+	my $self = shift;
+	my $ip = $_[0];
+
+	#  convert these items back into the integers from whence they came
+	my %rev_DIR = reverse %PF_DIR;
+	my %rev_ACTION = reverse %PF_ACTION;
+	my %rev_REASON = reverse %PF_REASON;
+
+	my $dir = $rev_DIR{$self->{dir}};
+	my $action = $rev_ACTION{$self->{action}};
+	my $reason = $rev_REASON{$self->{reason}};
+
+	# based on pfloghdr struct in:
+	# [OpenBSD]/src/sys/net/if_pflog.h r1.14
+	my $packet = pack("CCCCa16a16NNLlLlCa3a*", 
+		$self->{len}, $self->{af}, $action, $reason, $self->{ifname}, 
+		$self->{ruleset}, $self->{rulenr}, $self->{subrulenr},
+		$self->{uid}, $self->{pid}, $self->{rule_uid}, $self->{rule_pid},
+		$dir, $self->{pad}, $ip);
+
+	return $packet;
+}
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+C<NetPacket::PFLog> - Assembling and disassembling OpenBSD's Packet
+Filter log header.
+
+=head1 SYNOPSIS
+
+  use NetPacket::PFLog;
+
+  $pfl_obj = NetPacket::PFLog->decode($raw_pkt);
+  $pfl_pkt = NetPacket::PFLog->encode();
+  $pfl_data = NetPacket::PFLog::strip($raw_pkt);
+
+=head1 DESCRIPTION
+
+C<NetPacket::PFLog> provides a set of routines for assembling and
+disassembling the header attached to packets logged by OpenBSD's
+Packet Filter.  
+
+=head2 Methods
+
+=over
+
+=item C<NetPacket::PFLog-E<gt>decode([RAW PACKET])>
+
+Decode the raw packet data given and return an object containing
+instance data.  This method will quite happily decode garbage input. It
+is the responsibility of the programmer to ensure valid packet data is
+passed to this method.
+
+=item C<NetPacket::PFLog-E<gt>encode()>
+
+Return a PFLog packet encoded with the instance data specified.
+
+=back
+
+=head2 Functions
+
+=over
+
+=item C<NetPacket::PFLog::strip([RAW PACKET])>
+
+Return the actual packet logged by Packet Filter that the PFLog header
+is describing. This data is suitable to be used as input for other
+C<NetPacket::*> modules.
+
+This function is equivalent to creating an object using the
+C<decode()> constructor and returning the C<data> field of that
+object.
+
+=back
+
+=head2 Instance data
+
+The instance data for the C<NetPacket::PFLog> object consists of
+the following fields:
+
+=over
+
+=item len
+
+The length of the pflog header.
+
+=item af
+
+The Address Family which denotes if the packet is IPv4 or IPv6.
+
+=item action
+
+The action (block, pass, or scrub) that was taken on the packet.
+
+=item reason
+
+The reason that the action was taken.
+
+=item ifname
+
+The name of the interface the packet was passing through.
+
+=item ruleset
+
+The name of the subruleset that the matching rule is a member of. If
+the value is empty, the matching rule is in the main ruleset.
+
+=item rulenr
+
+The rule number that the packet matched.
+
+=item subrulenr
+
+The rule number in the subruleset that the packet matched. The value
+will be 2^32-1 if the packet matched in the main ruleset only.
+
+=item uid
+
+The uid of the local process that generated the packet that was logged, if
+applicable.
+
+=item pid
+
+The pid of the local process that generated the packet that was logged, if
+applicable.
+
+=item rule_uid
+
+The uid of the process that inserted the rule that caused the packet to be
+logged.
+
+=item rule_pid
+
+The pid of the process that inserted the rule that caused the packet to be
+logged.
+
+=item dir
+
+The direction the packet was travelling through the interface.
+
+=item pad
+
+Padding data.
+
+=item data
+
+The actual IPv4 or IPv6 packet that was logged by Packet Filter.
+
+=back
+
+=head2 Exports
+
+=over
+
+=item default
+
+none
+
+=item exportable
+
+Data Link Type:
+
+  DLT_PFLOG
+
+Strip function:
+
+  pflog_strip
+
+=item tags
+
+The following tags can be used to export certain items:
+
+=over
+
+=item C<:DLT>
+
+DLT_PFLOG
+
+=item C<:strip>
+
+The function C<pflog_strip>
+
+=item C<:ALL>
+
+All the above exportable items
+
+=back
+
+=back
+
+=head1 EXAMPLE
+
+The following prints the action, direction, interface name, and
+reason:
+
+  #!/usr/bin/perl -w
+
+  use strict;
+  use Net::PcapUtils;
+  use NetPacket::PFLog;
+
+  sub process_pkt {
+      my ($user, $hdr, $pkt) = @_;
+
+      my $pfl_obj = NetPacket::PFLog->decode($pkt);
+      print("$pfl_obj->{action} $pfl_obj->{dir} ");
+      print("on $pfl_obj->{ifname} ($pfl_obj->{reason})\n");
+  }
+
+  Net::PcapUtils::loop(\&process_pkt, FILTER => 'ip or ip6');
+
+=head1 TODO
+
+Nothing at this time.
+
+=head1 COPYRIGHT
+
+Copyright (c) 2003-2009 Joel Knight <knight.joel@gmail.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+=head1 AUTHOR
+
+Joel Knight E<lt>knight.joel@gmail.comE<gt>
+
+=cut
+
diff -pruN NetPacket-0.41.1.orig/lib/NetPacket/UDP.pm NetPacket-0.41.1/lib/NetPacket/UDP.pm
--- NetPacket-0.41.1.orig/lib/NetPacket/UDP.pm	Tue Jan  6 14:23:41 2009
+++ NetPacket-0.41.1/lib/NetPacket/UDP.pm	Sun Mar  1 12:03:24 2009
@@ -205,10 +205,10 @@ instance data.  This method will quite happily decode 
 It is the responsibility of the programmer to ensure valid packet data
 is passed to this method.
 
-=item C<NetPacket::UDP-E<gt>encode(param =E<gt> value)>
+=item C<NetPacket::UDP-E<gt>encode($ip_obj)>
 
 Return a UDP packet encoded with the instance data specified. Needs parts 
-of the ip header contained in $ip_obj, the IP object, in order to calculate 
+of the IP header contained in $ip_obj, the IP object, in order to calculate 
 the UDP checksum. The length field will also be set automatically.
 
 =back
@@ -268,9 +268,7 @@ none
 
 =item exportable
 
-igmp_strip IGMP_VERSION_RFC998 IGMP_VERSION_RFC1112
-IGMP_MSG_HOST_MQUERY IGMP_MSG_HOST_MREPORT IGMP_IP_NO_HOSTS
-IGMP_IP_ALL_HOSTS IGMP_IP_ALL_ROUTERS
+udp_strip
 
 =item tags
 
@@ -280,20 +278,8 @@ The following tags group together related exportable i
 
 =item C<:strip>
 
-Import the strip function C<igmp_strip>.
+Import the strip function C<udp_strip>.
 
-=item C<:versions>
-
-IGMP_VERSION_RFC998 IGMP_VERSION_RFC1112
-
-=item C<:msgtypes>
-
-IGMP_HOST_MQUERY IGMP_HOST_MREPORT
-
-=item C<:group_addrs>
-
-IGMP_IP_NO_HOSTS IGMP_IP_ALL_HOSTS IGMP_IP_ALL_ROUTERS
-
 =item C<:ALL>
 
 All the above exportable items.
@@ -304,8 +290,8 @@ All the above exportable items.
 
 =head1 EXAMPLE
 
-The following script dumps IGMP the contents of IGMP frames to
-standard output.
+The following example prints the source IP address and port, the
+destination IP address and port, and the UDP packet length:
 
   #!/usr/bin/perl -w
 
