diff --git a/sipdump.pl b/sipdump.pl new file mode 100644 index 0000000..d9f7293 --- /dev/null +++ b/sipdump.pl @@ -0,0 +1,136 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Net::Pcap; +use Getopt::Std; +use Net::Frame; +use Net::Frame::Layer::ETH; +use Net::Frame::Layer::ETH qw(:consts); +use Net::Frame::Layer::IPv4; +use Net::Frame::Layer::IPv4 qw(:consts); +use Net::Frame::Layer::TCP; +use Net::Frame::Layer::UDP; +use Net::Packet::Layer7; +use Net::SIP::Packet; +use Net::SIP::Response; +use Net::SIP::Request; + +my $pktcount=0; +my $curtime=0; +my $reftime=0; +my $endtime=0; +my $timelen=0; + +sub process_pkt +{ + my($user_data, $hdr, $pkt) = @_; + + $reftime = $hdr->{tv_sec} if ($reftime == 0); + $endtime = $hdr->{tv_sec}; + + $curtime = sprintf("%d\n", $hdr->{tv_sec} - $reftime); + $pktcount++; + + ## TODO: check if this is actually ethernet frame before decoding + my $eth = Net::Frame::Layer::ETH->new(raw => $pkt); + $eth->unpack(); + my $srcmac = $eth->src; + my $dstmac = $eth->dst; +# print "src-mac: $srcmac dst-mac: $dstmac "; + + return if ($eth->type != NF_ETH_TYPE_IPv4); + + my $raw=""; + + $raw = $eth->payload; + my $ipv4 = Net::Frame::Layer::IPv4->new(raw => $raw); + $ipv4->unpack(); + my $srcip = $ipv4->src; + my $dstip = $ipv4->dst; + + $raw = $ipv4->payload; + my $l4proto; + + if ($ipv4->protocol == NF_IPv4_PROTOCOL_TCP) + { + $l4proto = Net::Frame::Layer::TCP->new(raw => $raw); + $l4proto->unpack(); + } + + if ($ipv4->protocol == NF_IPv4_PROTOCOL_UDP) + { + $l4proto = Net::Frame::Layer::UDP->new(raw => $raw); + $l4proto->unpack(); + } + + my $tcppayload = $l4proto->payload; + if ((index $tcppayload, "INVITE ") eq 0) { + print "src-ip: $srcip dst-ip: $dstip "; + print "\n"; +# print "payload: $tcppayload\n"; + my $sip = Net::SIP::Packet->new($tcppayload); + print "From: \t" . $sip->get_header( 'From' ) . "\n"; + print "To: \t" . $sip->get_header( 'To' ) . "\n"; + print "UA: \t" . $sip->get_header( 'User-Agent' ) . "\n"; + } + + +} + +sub help { + print "sipdump [-h] -f pcapfile [-e filter expression]\n"; + print "\n"; + print "\t-h\t\thelp\n"; + print "\t-f pcapfile\tinput file name (required)\n"; + print "\t-e expression\tfilter expression (tcpdump compatible)\n"; + print "\n"; + exit(); +} + +sub dump_data { + my @data=@_; + + open(my $fh, ">", "temp.data"); + + for (my $i = 0; $i <= $timelen; $i++) { + print $fh "$i $data[$i]\n"; + } + + close($fh); +} + +#### main + +my $err =''; +my %opts=(); + +getopts('he:f:', \%opts); + +if (defined $opts{h}) { help(); } +if (not defined $opts{f}) { help(); } + +my $inputfile=$opts{f}; + +# process the pcap again, now do the bps and pps calculation +my $pcap = Net::Pcap::open_offline($inputfile,\$err) or die "Can't open file...$err\n"; + +my $filter="tcp or udp"; +$filter = $opts{e} if (defined $opts{e}); + +my $filter_t; +if (Net::Pcap::compile($pcap, \$filter_t, $filter, 1, 0) == -1) { + die "Unable to compile filter expression '$filter'\n"; + } +Net::Pcap::setfilter($pcap, $filter_t); + +Net::Pcap::loop($pcap, -1, \&process_pkt, ''); +Net::Pcap::close($pcap); + +$timelen = $endtime - $reftime; + +print STDERR "Packet Count:\t\t $pktcount\n"; +print STDERR "Capture Duration:\t $timelen seconds\n"; +print STDERR "Filter Expression:\t\t$filter\n"; + +