By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,811 Members | 1,978 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,811 IT Pros & Developers. It's quick & easy.

Packet Capturing Using PERL

P: 17
Hello……I am working on voice transmission control through linux as my project in high school……I need to know if the comments I have made on the following program are correct….

Object of the perl program is to build a network analyzer that captures local area network (LAN) traffic destined for the local domain name system (DNS) server and logs information on which IP addresses request which IP name resolutions.

Expand|Select|Wrap|Line Numbers
  1. <1 #!/usr/bin/perl -w
  2. 2 use 5.6.0; # Change to 5.006_000 if using Perl 5.8.0.
  3. 3 use strict;
  4. 4
  5. 5 use constant DNS_PORT => 53;# The DNS PORT is the standard protocol port number for DNS 
  6. 6 use constant HOWMANY => 100;# default number of packets to capture.
  7. 7
  8. 8 use Net::DNS::Packet;# A Net::DNS::Packet object represents a DNS packet.
  9. 9 use Net::PcapUtils;# Net::PcapUtils is a module to sit in front of Net::Pcap in order to hide some of the pcap(3) initialisation by providing sensible defaults. This enables a programmer to easily write small, specific scripts for a particular purpose without having to worry about too many details.
  10. 10 use NetPacket::Ethernet qw( :strip );
  11. 11 use NetPacket::IP;# NetPacket::IP provides a set of routines for assembling and disassembling packets using IP (Internet Protocol)
  12. 12 use NetPacket::UDP; # NetPacket::UDP provides a set of routines for assembling and disassembling packets using UDP (User Datagram Protocol).
  13. 13
  14. 14 our $num_processed = 0; # declare and define a global variable, $num processed, used to record the number of packets processed.
  15. 15
  16. 16 sub got_a_packet {
  17. 17 my $handle = shift ;# assigning the two parameters to $handle and $packet to append the results to the log file using $handle and use the contents of $packet to create a NetPacket::IP object.
  18. 18 my $packet = shift;
  19. 19
  20. 20 my $ip_datagram = NetPacket::IP->decode(
  21. 21 NetPacket::Ethernet::eth_strip( $packet ) ); # this subroutine removes the Ethernet frame from $packet and returns the IP datagram, and NetPacket::IP::decode extracts the IP data portion.
  22. 22
  23. 23 my $udp_datagram = NetPacket::UDP->decode( $ip_datagram->{data} );# extracting UDP datagram
  24. 24
  25. 25 if ( $udp_datagram->{dest_port} == DNS_PORT ) # ensuring that the destination port matches DNS PORT
  26. 26 {
  27. 27 my $dns_packet = $udp_datagram->{data};# assign the data portion of the UDP datagram to $dns packet.
  28. 28 my $dns_decode = Net::DNS::Packet->new( \$dns_packet );#decode the data portion from the IP packet
  29. 29 my @questions = $dns_decode->question; # extract the DNS queries from that and store them in @questions.
  30. 30
  31. 31 foreach my $q ( @questions ) # process each DNS query.
  32. 32 {
  33. 33 my $question = $q->string; # get the current query in
  34. stringified form,
  35. 34
  36. 35 unless ( $question =~ /in-addr\.arpa/ ) # skip queries that match in-addr.arpa since those relate to IP addresses,
  37. not names.
  38. 36 {
  39. 37 $question =~ /^(.+)\tIN/;
  40. 38
  41. 39 print "$ip_datagram->{src_ip} -> "; # 39-44 outputs the source and destination IP addresses together with the IP name to the screen and
  42. log-file.
  43. 40 print "$ip_datagram->{dest_ip}: ";
  44. 41 print "$1\n";
  45. 42 print $handle "$ip_datagram->{src_ip} -> ";
  46. 43 print $handle "$ip_datagram->{dest_ip}: ";
  47. 44 print $handle "$1\n";
  48. 45
  49. 46 $num_processed++;# increment $num processed 
  50. 47 }
  51. 48 }48 }
  52. 49 }
  53. 50 }
  54. 51
  55. 52 sub display_results {        #calling a ssubroutine
  56. 53 my $outof = shift;    #no. of packets actually processed in $outof
  57. 54
  58. 55 print "\nProcessed $num_processed (out of $outof) "; #prints  the results
  59. 56 print "UDP datagrams carrying DNS.\n\n";
  60. 57 }
  61. 58
  62. 59 my $count = shift || HOWMANY; # sets the number of packets to process. If a command line argument isn’t provided, it uses the
  63. value of HOWMANY
  64.  
  65. 60 my $rem_count = $count;
  66. 61 my $pkt_descriptor = Net::PcapUtils::open(        # it places the Ethernet card into promiscuous mode for packet capturing
  67. 62 FILTER => ’udp’,            #DNS uses UDP as a protocol filter
  68. 63 SNAPLEN => 1500 );        # 1500 bytes is the maximum payload size on Ethernet networks
  69. 64
  70. 65 if ( !ref( $pkt_descriptor ) )    # $pkt descriptor is reference to a valid packet capture descriptor
  71. 66 {
  72. 67 warn "Net::PcapUtils::open returned: $pkt_descriptor\n";    # If it fails it returns an error message and then exit
  73. 68 exit;
  74. 69 }
  75. 70
  76. 71 open WDW_FILE, ">>wdw_log.txt"
  77. 72 or die "Could not append to wdw_log.txt: $!\n";    # open the log file in append mode
  78. 73
  79. 74 print WDW_FILE "\n", scalar localtime, " - wdw BEGIN run.\n\n";    #timestamp it at the beginning of the run
  80. 75
  81. 76 while ( $count)    #This subroutine waits for a UDP packet then returns two values—a scalar which represents the raw Ethernet packet, which I store in $packet, and a hash, which is of no nee
  82. 77 {
  83. 78 my ( $packet, %header ) = Net::PcapUtils::next( $pkt_descriptor );    #call the Net::PcapUtils::next subroutine with packet capture descriptor in $pkt descriptor, saves the UDP packet in $packet
  84. 79 got_a_packet( *WDW_FILE, $packet );    #sending the output from got a packet to this file
  85. 80 $count--;
  86. 81 }
  87. 82
  88. 83 print WDW_FILE "\n", scalar localtime, " - wdw END run.\n";    #timestamp it at the beginning of the run
  89.  
  90. 84 close WDW_FILE;     #closes the file
  91. 85
  92. 86 display_results( $rem_count );    #prints the initial value of $count before the while loop started at line 76>
  93.  
Mar 19 '10 #1
Share this Question
Share on Google+
3 Replies


P: 17
Hello……I am working on voice transmission control through linux as my project in high school……I need to know if the comments I have made on the following program are correct….

Object of the perl program is to build a network analyzer that captures local area network (LAN) traffic destined for the local domain name system (DNS) server and logs information on which IP addresses request which IP name resolutions.

Expand|Select|Wrap|Line Numbers
  1.  
  2.    1. <1 #!/usr/bin/perl -w
  3.    2. 2 use 5.6.0; # Change to 5.006_000 if using Perl 5.8.0.
  4.    3. 3 use strict;
  5.    4. 4
  6.    5. 5 use constant DNS_PORT => 53;# The DNS PORT is the standard protocol port number for DNS 
  7.    6. 6 use constant HOWMANY => 100;# default number of packets to capture.
  8.    7. 7
  9.    8. 8 use Net::DNS::Packet;# A Net::DNS::Packet object represents a DNS packet.
  10.    9. 9 use Net::PcapUtils;# Net::PcapUtils is a module to sit in front of Net::Pcap in order to hide some of the pcap(3) initialisation by providing sensible defaults. This enables a programmer to easily write small, specific scripts for a particular purpose without having to worry about too many details.
  11.   10. 10 use NetPacket::Ethernet qw( :strip );
  12.   11. 11 use NetPacket::IP;# NetPacket::IP provides a set of routines for assembling and disassembling packets using IP (Internet Protocol)
  13.   12. 12 use NetPacket::UDP; # NetPacket::UDP provides a set of routines for assembling and disassembling packets using UDP (User Datagram Protocol).
  14.   13. 13
  15.   14. 14 our $num_processed = 0; # declare and define a global variable, $num processed, used to record the number of packets processed.
  16.   15. 15
  17.   16. 16 sub got_a_packet {
  18.   17. 17 my $handle = shift ;# assigning the two parameters to $handle and $packet to append the results to the log file using $handle and use the contents of $packet to create a NetPacket::IP object.
  19.   18. 18 my $packet = shift;
  20.   19. 19
  21.   20. 20 my $ip_datagram = NetPacket::IP->decode(
  22.   21. 21 NetPacket::Ethernet::eth_strip( $packet ) ); # this subroutine removes the Ethernet frame from $packet and returns the IP datagram, and NetPacket::IP::decode extracts the IP data portion.
  23.   22. 22
  24.   23. 23 my $udp_datagram = NetPacket::UDP->decode( $ip_datagram->{data} );# extracting UDP datagram
  25.   24. 24
  26.   25. 25 if ( $udp_datagram->{dest_port} == DNS_PORT ) # ensuring that the destination port matches DNS PORT
  27.   26. 26 {
  28.   27. 27 my $dns_packet = $udp_datagram->{data};# assign the data portion of the UDP datagram to $dns packet.
  29.   28. 28 my $dns_decode = Net::DNS::Packet->new( \$dns_packet );#decode the data portion from the IP packet
  30.   29. 29 my @questions = $dns_decode->question; # extract the DNS queries from that and store them in @questions.
  31.   30. 30
  32.   31. 31 foreach my $q ( @questions ) # process each DNS query.
  33.   32. 32 {
  34.   33. 33 my $question = $q->string; # get the current query in
  35.   34. stringified form,
  36.   35. 34
  37.   36. 35 unless ( $question =~ /in-addr\.arpa/ ) # skip queries that match in-addr.arpa since those relate to IP addresses,
  38.   37. not names.
  39.   38. 36 {
  40.   39. 37 $question =~ /^(.+)\tIN/;
  41.   40. 38
  42.   41. 39 print "$ip_datagram->{src_ip} -> "; # 39-44 outputs the source and destination IP addresses together with the IP name to the screen and
  43.   42. log-file.
  44.   43. 40 print "$ip_datagram->{dest_ip}: ";
  45.   44. 41 print "$1\n";
  46.   45. 42 print $handle "$ip_datagram->{src_ip} -> ";
  47.   46. 43 print $handle "$ip_datagram->{dest_ip}: ";
  48.   47. 44 print $handle "$1\n";
  49.   48. 45
  50.   49. 46 $num_processed++;# increment $num processed 
  51.   50. 47 }
  52.   51. 48 }48 }
  53.   52. 49 }
  54.   53. 50 }
  55.   54. 51
  56.   55. 52 sub display_results {        #calling a ssubroutine
  57.   56. 53 my $outof = shift;    #no. of packets actually processed in $outof
  58.   57. 54
  59.   58. 55 print "\nProcessed $num_processed (out of $outof) "; #prints  the results
  60.   59. 56 print "UDP datagrams carrying DNS.\n\n";
  61.   60. 57 }
  62.   61. 58
  63.   62. 59 my $count = shift || HOWMANY; # sets the number of packets to process. If a command line argument isn’t provided, it uses the
  64.   63. value of HOWMANY
  65.   64.  
  66.   65. 60 my $rem_count = $count;
  67.   66. 61 my $pkt_descriptor = Net::PcapUtils::open(        # it places the Ethernet card into promiscuous mode for packet capturing
  68.   67. 62 FILTER => ’udp’,            #DNS uses UDP as a protocol filter
  69.   68. 63 SNAPLEN => 1500 );        # 1500 bytes is the maximum payload size on Ethernet networks
  70.   69. 64
  71.   70. 65 if ( !ref( $pkt_descriptor ) )    # $pkt descriptor is reference to a valid packet capture descriptor
  72.   71. 66 {
  73.   72. 67 warn "Net::PcapUtils::open returned: $pkt_descriptor\n";    # If it fails it returns an error message and then exit
  74.   73. 68 exit;
  75.   74. 69 }
  76.   75. 70
  77.   76. 71 open WDW_FILE, ">>wdw_log.txt"
  78.   77. 72 or die "Could not append to wdw_log.txt: $!\n";    # open the log file in append mode
  79.   78. 73
  80.   79. 74 print WDW_FILE "\n", scalar localtime, " - wdw BEGIN run.\n\n";    #timestamp it at the beginning of the run
  81.   80. 75
  82.   81. 76 while ( $count)    #This subroutine waits for a UDP packet then returns two values—a scalar which represents the raw Ethernet packet, which I store in $packet, and a hash, which is of no nee
  83.   82. 77 {
  84.   83. 78 my ( $packet, %header ) = Net::PcapUtils::next( $pkt_descriptor );    #call the Net::PcapUtils::next subroutine with packet capture descriptor in $pkt descriptor, saves the UDP packet in $packet
  85.   84. 79 got_a_packet( *WDW_FILE, $packet );    #sending the output from got a packet to this file
  86.   85. 80 $count--;
  87.   86. 81 }
  88.   87. 82
  89.   88. 83 print WDW_FILE "\n", scalar localtime, " - wdw END run.\n";    #timestamp it at the beginning of the run
  90.   89.  
  91.   90. 84 close WDW_FILE;     #closes the file
  92.   91. 85
  93.   92. 86 display_results( $rem_count );    #prints the initial value
  94.  
  95.  
Mar 21 '10 #2

numberwhun
Expert Mod 2.5K+
P: 3,503
Sorry Sidra, but I don't have any experience with packet capturing with Perl. I typically use WireShark for that. My suggestion, if you don't get an answer here, is to post this same question on Perlmonks.org.

Regards,

Jeff
Mar 21 '10 #3

P: 17
Thank you very much Jeff. I will certainly do that.

Regards
Mar 30 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.