Skip to content

Commit

Permalink
Add tools to read pcap and convert network layers to JSON.
Browse files Browse the repository at this point in the history
  • Loading branch information
rcaputo committed Jun 9, 2011
1 parent 4e2502c commit 4ebaf97
Show file tree
Hide file tree
Showing 14 changed files with 247 additions and 0 deletions.
7 changes: 7 additions & 0 deletions bin/jeth2ip
@@ -0,0 +1,7 @@
#!/usr/bin/perl
use App::PipeFilter::JsonEthernetToIp;
exit App::PipeFilter::JsonEthernetToIp->new_with_options()->run();

__END__
# vim: ts=2 sw=2 expandtab
7 changes: 7 additions & 0 deletions bin/jip2udp
@@ -0,0 +1,7 @@
#!/usr/bin/perl
use App::PipeFilter::JsonIpToUdp;
exit App::PipeFilter::JsonIpToUdp->new_with_options()->run();

__END__
# vim: ts=2 sw=2 expandtab
7 changes: 7 additions & 0 deletions bin/jpcap2eth
@@ -0,0 +1,7 @@
#!/usr/bin/perl
use App::PipeFilter::JsonPcapToEthernet;
exit App::PipeFilter::JsonPcapToEthernet->new_with_options()->run();

__END__
# vim: ts=2 sw=2 expandtab
7 changes: 7 additions & 0 deletions bin/pcap2json
@@ -0,0 +1,7 @@
#!/usr/bin/perl
use App::PipeFilter::PcapToJson;
exit App::PipeFilter::PcapToJson->new_with_options()->run();

__END__
# vim: ts=2 sw=2 expandtab
11 changes: 11 additions & 0 deletions lib/App/PipeFilter/JsonEthernetToIp.pm
@@ -0,0 +1,11 @@
package App::PipeFilter::JsonEthernetToIp;

use Moose;
extends 'App::PipeFilter::Generic::Json';
with 'App::PipeFilter::Role::Transform::EthernetToIp';

1;

__END__
# vim: ts=2 sw=2 expandtab
11 changes: 11 additions & 0 deletions lib/App/PipeFilter/JsonIpToUdp.pm
@@ -0,0 +1,11 @@
package App::PipeFilter::JsonIpToUdp;

use Moose;
extends 'App::PipeFilter::Generic::Json';
with 'App::PipeFilter::Role::Transform::IpToUdp';

1;

__END__
# vim: ts=2 sw=2 expandtab
11 changes: 11 additions & 0 deletions lib/App/PipeFilter/JsonPcapToEthernet.pm
@@ -0,0 +1,11 @@
package App::PipeFilter::JsonPcapToEthernet;

use Moose;
extends 'App::PipeFilter::Generic::Json';
with 'App::PipeFilter::Role::Transform::PcapToEthernet';

1;

__END__
# vim: ts=2 sw=2 expandtab
18 changes: 18 additions & 0 deletions lib/App/PipeFilter/PcapToJson.pm
@@ -0,0 +1,18 @@
package App::PipeFilter::PcapToJson;

use Moose;
extends 'App::PipeFilter::Generic';

with (
"App::PipeFilter::Role::Opener::PcapInput",
"App::PipeFilter::Role::Reader::Pcap",
"App::PipeFilter::Role::Input::ArrayBuffer",
"App::PipeFilter::Role::Transform::None",
"App::PipeFilter::Role::Output::Json",
);

1;

__END__
# vim: ts=2 sw=2 expandtab
19 changes: 19 additions & 0 deletions lib/App/PipeFilter/Role/Input/ArrayBuffer.pm
@@ -0,0 +1,19 @@
package App::PipeFilter::Role::Input::ArrayBuffer;

use Moose::Role;

sub decode_input {
my ($self, $buffer_ref) = @_;

my @return = @$$buffer_ref;
$$buffer_ref = "";

return @return;
}

no Moose::Role;
1;

__END__
# vim: ts=2 sw=2 expandtab
21 changes: 21 additions & 0 deletions lib/App/PipeFilter/Role/Opener/PcapInput.pm
@@ -0,0 +1,21 @@
package App::PipeFilter::Role::Opener::PcapInput;

use Moose::Role;
use Net::Pcap qw(pcap_open_offline);

sub open_input {
my ($self, $filename) = @_;

my $err = "";
my $pcap = pcap_open_offline($filename, \$err);
die "unable to open pcap $filename: $err" unless defined $pcap;

return $pcap;
}

no Moose::Role;
1;

__END__
# vim: ts=2 sw=2 expandtab
30 changes: 30 additions & 0 deletions lib/App/PipeFilter/Role/Reader/Pcap.pm
@@ -0,0 +1,30 @@
package App::PipeFilter::Role::Reader::Pcap;

use Moose::Role;
use Net::Pcap qw(pcap_next);

sub read_input {
my ($self, $ifh, $buffer_ref) = @_;

my %header;
my $packet = pcap_next($ifh, \%header);

return unless defined $packet;

$$buffer_ref = [
{
( map { ("pcap_$_", $header{$_}) } keys %header ),
# Binary data saved as hex to avoid UTF-8-ification.
pcap_data => unpack("H*", $packet),
}
];

return 1;
}

no Moose::Role;
1;

__END__
# vim: ts=2 sw=2 expandtab
39 changes: 39 additions & 0 deletions lib/App/PipeFilter/Role/Transform/EthernetToIp.pm
@@ -0,0 +1,39 @@
package App::PipeFilter::Role::Transform::EthernetToIp;

use Moose::Role;
use NetPacket::IP;

sub transform {
return(
map {
my $ip = NetPacket::IP->decode(pack "H*", delete $_->{eth_data});

# Not sure why the + is required, but it makes all the difference.
+{
%$_,
ip_len => $ip->{len},
ip_dest_ip => $ip->{dest_ip},
ip_options => $ip->{options},
ip_ttl => $ip->{ttl},
ip_src_ip => $ip->{src_ip},
ip_tos => $ip->{tos},
ip_id => $ip->{id},
ip_hlen => $ip->{hlen},
ip_proto => $ip->{proto},
ip_foffset => $ip->{foffset},
ip_flags => $ip->{flags},
ip_ver => $ip->{ver},
ip_cksum => $ip->{cksum},
ip_data => unpack("H*", $ip->{data}),
};
}
# Skips $self in $_[0].
@_[1..$#_]
);
}

1;

__END__
# vim: ts=2 sw=2 expandtab
30 changes: 30 additions & 0 deletions lib/App/PipeFilter/Role/Transform/IpToUdp.pm
@@ -0,0 +1,30 @@
package App::PipeFilter::Role::Transform::IpToUdp;

use Moose::Role;
use NetPacket::UDP;

sub transform {
return(
map {
my $udp = NetPacket::UDP->decode(pack "H*", delete $_->{ip_data});

# Not sure why the + is required, but it makes all the difference.
+{
%$_,
udp_cksum => $udp->{cksum},
udp_data => unpack("H*", $udp->{data}),
udp_dest_port => $udp->{dest_port},
udp_len => $udp->{len},
udp_src_port => $udp->{src_port},
};
}
# Skips $self in $_[0].
@_[1..$#_]
);
}

1;

__END__
# vim: ts=2 sw=2 expandtab
29 changes: 29 additions & 0 deletions lib/App/PipeFilter/Role/Transform/PcapToEthernet.pm
@@ -0,0 +1,29 @@
package App::PipeFilter::Role::Transform::PcapToEthernet;

use Moose::Role;
use NetPacket::Ethernet;

sub transform {
return(
map {
my $eth = NetPacket::Ethernet->decode(pack "H*", delete $_->{pcap_data});

# Not sure why the + is required, but it makes all the difference.
+{
%$_,
eth_data => unpack("H*", $eth->{data}),
eth_dest_mac => $eth->{dest_mac},
eth_src_mac => $eth->{src_mac},
eth_type => $eth->{type},
};
}
# Skips $self in $_[0].
@_[1..$#_]
);
}

1;

__END__
# vim: ts=2 sw=2 expandtab

0 comments on commit 4ebaf97

Please sign in to comment.