Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

my first packet sniffer in perl

by hnd (Scribe)
on Jun 29, 2009 at 11:15 UTC ( [id://775620]=perlmeditation: print w/replies, xml ) Need Help??

hello every one.....
i made this packet sniffer while experimneting with Net::Pcap module...... and it kinda...... works (wow 8-o)
so here it goes

use Net::Pcap; use strict; #i am very careless #look up a device to be used (the active NIC) my $err="blah"; my $dev=Net::Pcap::lookup_dev(\$err) or die "error:\t$err\n"; #open the device in live mode to sniff out packets my ($promisc,$snaplen,$to_ms); $promisc=1; #watchout for any damn packet $snaplen=150; #atleast 80 chars $to_ms=100; #wait for 1 sec $pcap=Net::Pcap::open_live($dev,$snaplen,$promisc,$to_ms); #loop infinitely until an error occurs #and call the packet processing subroutine Net::Pcap::loop($pcap,-1,\&pack_pro,0); sub pack_pro{ #this is the actual packet processor my($user_data,$header,$packet)=@_; # extract the source IP addr into dotted quad form my($source) = sprintf("%d.%d.%d.%d", ord( substr($packet, $src_ip, 1) ), ord( substr($packet, $src_ip+1, 1) ), ord( substr($packet, $src_ip+2, 1) ), ord( substr($packet, $src_ip+3, 1) )); # extract the destination IP addr into dotted quad form my($destination) = sprintf("%d.%d.%d.%d", ord( substr($packet, $dst_ip, 1) ), ord( substr($packet, $dst_ip+1, 1) ), ord( substr($packet, $dst_ip+2, 1) ), ord( substr($packet, $dst_ip+3, 1) )); #the above part is directly taken from "hacking linux exposed" (sorry +but couldn't figure out this part) my $data=substr($packet,$domain_start); #change domain component seperator back into dots $data=~s/[^-A-Za-z0-9]/./g; #print the packet print "$source->$destination\n$data\n"; }#sub routine ends

i thought of coding it in C but steadily perl is taking over as the more preferred language......
please do give the feedback......
i need it.....

Replies are listed 'Best First'.
Re: my first packet sniffer in perl
by toolic (Bishop) on Jun 29, 2009 at 13:54 UTC
    please do give the feedback......
    You should post code that someone can download and compile without errors. Since you are new to the Monastery, you should re-read Writeup Formatting Tips, then try to download the code yourself, and try to run it. It is full of "br" tags, and the code itself has syntax errors:

    Do not capitalize 'strict': use strict;

    $pkt was never assigned a value; you probably meant to use $packet.

    $data=~s/[^-A-Za-z0-9]/./g needs a semicolon at the end. Also, you could take advantage of regular expression CHARACTER CLASSES to make the code less 'noisy'.

    Your code would be easier on the eyes if you made better use of whitespace. Try running your code through perltidy.

    any suggestions (or abuse) would be gladly accepted at the same email id
    The convention here at the Monastery is to provide constructive feedback as a reply to your node here, not via email.

    Update:

    use Strict; #i usually don't use it
    You should always use strict and warnings.
      i think that now its ok.......
      and i never meant i dont use strict i wrote it by mistake....... sorry........
      and the character classes.......... um.... i cant figure out what could be more efficient.......
      anyways is the overall code fine?????

        so you thought "I'll just add use Strict; then they won't know how slack a programmer I really am.". Unfortunately, as is evident from the replies you already have, bad habits shine through. Always use strictures (use strict; use warnings; - see The strictures, according to Seuss).


        True laziness is hard work
Re: my first packet sniffer in perl
by jwkrahn (Abbot) on Jun 29, 2009 at 14:56 UTC
    # extract the source IP addr into dotted quad form my($source) = sprintf("%d.%d.%d.%d", ord( substr($packet, $src_ip, 1) ), ord( substr($packet, $src_ip+1, 1) ), ord( substr($packet, $src_ip+2, 1) ), ord( substr($packet, $src_ip+3, 1) )); # extract the destination IP addr into dotted quad form my($destination) = sprintf("%d.%d.%d.%d", ord( substr($packet, $dst_ip, 1) ), ord( substr($packet, $dst_ip+1, 1) ), ord( substr($packet, $dst_ip+2, 1) ), ord( substr($packet, $dst_ip+3, 1) )); #the above part is directly taken from "hacking linux exposed" (sorry +but couldn't figure out this part)

    An easier way to do that is through the Socket module:

    use Socket; # extract the source IP addr into dotted quad form my $source = inet_ntoa substr $packet, $src_ip, 4; # extract the destination IP addr into dotted quad form my $destination = inet_ntoa substr $packet, $dst_ip, 4;
      hey...... thats obviously better!!!!!!!
      now why didnt i thought of it......
Re: my first packet sniffer in perl
by davorg (Chancellor) on Jun 29, 2009 at 13:58 UTC
    use Strict; #i usually don't use it

    And you're not really using it here. There's no module called "Strict.pm", it's "strict.pm". Capitalisation is important and a good programmer needs an eye for detail like that.

    Update: Just noticed this too.

    $snaplen=150; #atleast 80 chars
    $to_ms=100; #wait for 1 sec

    Are you deliberately writing comments that don't match the code? Are you trying to confuse anyone who maintains your code?

    --

    See the Copyright notice on my home node.

    Perl training courses

      um....no
      the $snaplen thing is the ssize of the data in the packet
      actually it was 135 but i rounded it off to nearest 50 :/
      and the $to_ms thing is the time to wait for a packet
        the $to_ms thing is the time to wait for a packet

        Right. The time to wait in milliseconds. You've set it to 100 milliseconds. But your comment says you've set it to one second. 100 milliseconds is not one second. Hence, it's a confusing comment.

        --

        See the Copyright notice on my home node.

        Perl training courses

Re: my first packet sniffer in perl
by marto (Cardinal) on Jun 29, 2009 at 14:22 UTC
    $to_ms=100; #wait for 1 sec $pcap=Net::Pcap::open_live($dev,$snaplen,$promisc,$to_ms);

    100 miliseconds is a tenth of a second, not one second.

    Martin

Re: my first packet sniffer in perl
by dev2dev (Initiate) on Nov 12, 2010 at 11:04 UTC
    Hi eveyone. I was trying this code and I firsted installed Net::Pcap module but it said I need to install wincap drives from wincap.org/install so I did and installed it. But when I run the script its giving compilation error 'unable to find module Net::Pcap I reinstalled but still no luck. I searched in c:\perl\lib but surprisingly it is not there not even in c:\perl\site\lib. Can anyone help me with this please.

      Perhaps show how you tried to install this, and the output of what happened?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://775620]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-03-19 02:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found