[PATCH 2/2] Add helper script pcap2ulog

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This script uses the Net::Pcap Perl library to parse an pcap file and
send packets to ulogd2 throught the UNIXSOCK input module.

Signed-off-by: Pierre Chifflier <chifflier@xxxxxxxxxxxx>
---
 contrib/pcap2ulog |  166 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 166 insertions(+), 0 deletions(-)
 create mode 100755 contrib/pcap2ulog

diff --git a/contrib/pcap2ulog b/contrib/pcap2ulog
new file mode 100755
index 0000000..65fd5ab
--- /dev/null
+++ b/contrib/pcap2ulog
@@ -0,0 +1,166 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2009-2010 Pierre Chifflier <chifflier@xxxxxx>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the same terms as Perl itself, either Perl version 5.8.4 or,
+# at your option, any later version of Perl 5 you may have available.
+
+use strict;
+
+use IO::Socket;
+use Net::Pcap;
+
+my $ULOGD_SOCKET_MARK = 0x41c90fd4;
+
+my $dumpfile = shift or die "Unable to open pcap file";
+my($pcap_t, $err);
+my($ulogd_client);
+my $socketfile = "/var/run/ulogd2.sock";
+my $data_buffer;
+my $linktype;
+my $proto_offset;
+
+my %linktype_to_offset = (
+	Net::Pcap::DLT_LINUX_SLL => 14,
+	Net::Pcap::DLT_EN10MB => 12,
+);
+
+sub connect_ulogd2 {
+    (-S $socketfile) or die "ulogd2 socket $socketfile does not exist - is ulogd running ?";
+
+    $ulogd_client = IO::Socket::UNIX->new(Peer  => $socketfile,
+                                          Type      => SOCK_STREAM ) or die $!;
+    $ulogd_client->autoflush(0);
+}
+
+sub print_padding
+{
+    my ($offset) = @_;
+    my $padding;
+    my $align = 8;
+    my $data;
+
+    $padding = ($align - ($offset % $align)) % $align;
+    #print "offset: $offset padding $padding\n";
+
+    $data = "\0" x $padding;
+    $data_buffer .= $data;
+}
+
+sub process_pkt {
+    my($user, $hdr, $pkt) = @_;
+
+    if (($user ne "xyz") or !defined($hdr) or !defined($pkt)) {
+        print("Bad args passed to callback\n");
+        print("Bad user data\n"), if ($user ne "xyz");
+        print("Bad pkthdr\n"), if (!defined($hdr));
+        print("Bad pkt data\n"), if (!defined($pkt));
+        print("not ok\n");
+        exit;
+    }
+
+    #print "Header: len $hdr->{len}\n";
+    #my $len = length $pkt;
+    #print "Packet length: $len\n";
+
+    my $size = length($pkt) - ($proto_offset+2);
+
+    #my $pcaphdr = unpack ("H*", substr ($pkt, 0, 16));
+    #printf("pcap hdr: $pcaphdr\n");
+    my $proto = unpack ("H*", substr ($pkt, $proto_offset, 2));
+    #printf("proto: $proto\n");
+
+    if ($proto ne "0800") {
+      print "ignoring packet with proto $proto\n";
+      return;
+    }
+
+    #my $ip_firstbyte = unpack ("H*", substr ($pkt, $proto_offset+2, 2));
+    #printf("ip_firstbyte: $ip_firstbyte\n");
+
+    # decode packet for a SLL:
+    # packet type (sent by us: 4)
+    # link layer address type: 1
+    # link layer address length: 6
+    # src dst
+    # protocol (IP, ARP, PPP, SNMP ...)
+    # data
+    my $srcmac = substr ($pkt, 6, 6);
+
+    (my $hex_src = unpack("H*", $srcmac)) =~ s/(..)/$1:/g;
+    chop $hex_src;
+    #printf "source mac: $hex_src\n";
+
+    my $hex_dst = "\0";
+
+    # format data
+    my $data;
+
+    $data_buffer = undef;
+
+    # ulogd packet signature
+    $data = pack ('N', $ULOGD_SOCKET_MARK);
+
+    $data_buffer .= $data;
+
+    my $options_num=2;
+    my $options_len=length($hex_src) + length($hex_dst);
+    # total length (will be filled later)
+    my $total_size = 0;
+    $data = pack ('n', $total_size);
+    $data_buffer .= $data;
+
+    # payload length + reserved + payload
+    $data = pack ('nNa*', $size, 0, substr($pkt,$proto_offset+2,$size));
+    $data_buffer .= $data;
+    print_padding($size);
+
+    # options
+    my $OOB_IN = 2;
+    $data = pack ('nna*', $OOB_IN, length($hex_src), $hex_src);
+    $data_buffer .= $data;
+    print_padding(length($hex_src));
+    my $OOB_OUT = 3;
+    $data = pack ('nna*', $OOB_OUT, length($hex_dst), $hex_dst);
+    $data_buffer .= $data;
+    print_padding(length($hex_dst));
+
+    # replace total size in buffer
+    my $l = length($data_buffer) - 4;
+    substr($data_buffer, 4, 2) = pack('n', $l);
+
+    #(my $hex = unpack("H*", $data_buffer)) =~ s/(..)/$1 /g;
+    #print "$l will be encoded as " . unpack("H*", pack('n', $l)) . "\n";
+    #print $hex, "\n";
+
+    print $ulogd_client $data_buffer;
+
+    $ulogd_client->flush;
+
+    #exit;
+}
+
+
+connect_ulogd2 or die $!;
+
+$pcap_t = Net::Pcap::open_offline($dumpfile, \$err);
+if (!defined($pcap_t)) {
+    print("Net::Pcap::dump_open failed: ", Net::Pcap::geterr($pcap_t), "\n");
+    exit;
+}
+
+$linktype = Net::Pcap::pcap_datalink($pcap_t);
+
+if (not exists $linktype_to_offset{$linktype}) {
+	print("Unsupported link type ", Net::Pcap::pcap_datalink_val_to_name($linktype), "\n");
+	exit 1;
+}
+
+$proto_offset = $linktype_to_offset{$linktype};
+
+Net::Pcap::loop($pcap_t, -1, \&process_pkt, "xyz");
+Net::Pcap::close($pcap_t);
+
+
+
-- 
1.7.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux