line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# Net::PcapUtils |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# Some code to abstract away some of the messier parts of using the |
5
|
|
|
|
|
|
|
# Net::Pcap library. The idea is to be able to write "one-liner" type |
6
|
|
|
|
|
|
|
# scripts for packet capture without getting bogged down in the |
7
|
|
|
|
|
|
|
# initialisation code. |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# Please send comments/suggestions to tpot@acsys.anu.edu.au |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# $Id: PcapUtils.pm,v 1.5 1999/04/07 01:33:24 tpot Exp $ |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
package Net::PcapUtils; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
# |
17
|
|
|
|
|
|
|
# Copyright (c) 1995,1996,1997,1998,1999 ANU and CSIRO on behalf of |
18
|
|
|
|
|
|
|
# the participants in the CRC for Advanced Computational Systems |
19
|
|
|
|
|
|
|
# ('ACSys'). |
20
|
|
|
|
|
|
|
# |
21
|
|
|
|
|
|
|
# ACSys makes this software and all associated data and documentation |
22
|
|
|
|
|
|
|
# ('Software') available free of charge. You may make copies of the |
23
|
|
|
|
|
|
|
# Software but you must include all of this notice on any copy. |
24
|
|
|
|
|
|
|
# |
25
|
|
|
|
|
|
|
# The Software was developed for research purposes and ACSys does not |
26
|
|
|
|
|
|
|
# warrant that it is error free or fit for any purpose. ACSys |
27
|
|
|
|
|
|
|
# disclaims any liability for all claims, expenses, losses, damages |
28
|
|
|
|
|
|
|
# and costs any user may incur as a result of using, copying or |
29
|
|
|
|
|
|
|
# modifying the Software. |
30
|
|
|
|
|
|
|
# |
31
|
|
|
|
|
|
|
|
32
|
2
|
|
|
2
|
|
6823
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
70
|
|
33
|
2
|
|
|
2
|
|
8
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
194
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my $myclass; |
36
|
|
|
|
|
|
|
BEGIN { |
37
|
2
|
|
|
2
|
|
4
|
$myclass = __PACKAGE__; |
38
|
2
|
|
|
|
|
171
|
$VERSION = "0.01"; |
39
|
|
|
|
|
|
|
} |
40
|
0
|
|
|
0
|
|
|
sub Version () { "$myclass v$VERSION" } |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
BEGIN { |
43
|
2
|
|
|
2
|
|
32
|
@ISA = qw(Exporter); |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# Items to export into callers namespace by default |
46
|
|
|
|
|
|
|
# (move infrequently used names to @EXPORT_OK below) |
47
|
|
|
|
|
|
|
|
48
|
2
|
|
|
|
|
11
|
@EXPORT = qw( |
49
|
|
|
|
|
|
|
); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Other items we are prepared to export if requested |
52
|
|
|
|
|
|
|
|
53
|
2
|
|
|
|
|
4
|
@EXPORT_OK = qw( |
54
|
|
|
|
|
|
|
); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Tags: |
57
|
|
|
|
|
|
|
|
58
|
2
|
|
|
|
|
52
|
%EXPORT_TAGS = ( |
59
|
|
|
|
|
|
|
ALL => [@EXPORT, @EXPORT_OK], |
60
|
|
|
|
|
|
|
); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
2
|
|
|
2
|
|
3309
|
use Net::Pcap 0.03; # Not all functions implemented in previous Net::Pcap's |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# |
67
|
|
|
|
|
|
|
# Set up Net::Pcap to capture packets live from the wire, or play back |
68
|
|
|
|
|
|
|
# packets from a savefile. Call a Perl subroutine for each packet |
69
|
|
|
|
|
|
|
# received. |
70
|
|
|
|
|
|
|
# |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub loop { |
73
|
|
|
|
|
|
|
my($callback, @rest) = @_; |
74
|
|
|
|
|
|
|
my($errbuf, $bpf_prog); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# Default arguments |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
my %args = ( |
79
|
|
|
|
|
|
|
SNAPLEN => 100, # Num bytes to capture from packet |
80
|
|
|
|
|
|
|
PROMISC => 1, # Operate in promiscuous mode? |
81
|
|
|
|
|
|
|
TIMEOUT => 1000, # Read timeout (ms) |
82
|
|
|
|
|
|
|
NUMPACKETS => -1, # Pkts to read (-1 = loop forever) |
83
|
|
|
|
|
|
|
FILTER => '', # Filter string |
84
|
|
|
|
|
|
|
USERDATA => '', # Passed as first arg to callback fn |
85
|
|
|
|
|
|
|
SAVEFILE => '', # Default save file |
86
|
|
|
|
|
|
|
DEV => '', # Network interface to open |
87
|
|
|
|
|
|
|
mode => '', # Internal variable |
88
|
|
|
|
|
|
|
@rest); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# Get pcap device if not specified |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
if ($args{DEV} eq '') { |
93
|
|
|
|
|
|
|
$args{DEV} = Net::Pcap::lookupdev(\$errbuf); |
94
|
|
|
|
|
|
|
return $errbuf, unless $args{DEV}; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# Get pcap network/netmask |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
my($net, $mask); |
100
|
|
|
|
|
|
|
return $errbuf, if (Net::Pcap::lookupnet($args{DEV}, \$net, \$mask, |
101
|
|
|
|
|
|
|
\$errbuf) == -1); |
102
|
|
|
|
|
|
|
# |
103
|
|
|
|
|
|
|
# Open in specified mode |
104
|
|
|
|
|
|
|
# |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
my $pcap_desc; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
if ($args{SAVEFILE} eq '') { |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Open interface "live" |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
$pcap_desc = Net::Pcap::open_live($args{DEV}, $args{SNAPLEN}, |
113
|
|
|
|
|
|
|
$args{PROMISC}, |
114
|
|
|
|
|
|
|
$args{TIMEOUT}, |
115
|
|
|
|
|
|
|
\$errbuf); |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
return $errbuf, unless $pcap_desc; |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
} else { |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# Open saved file |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
$pcap_desc = Net::Pcap::open_offline($args{SAVEFILE}, \$errbuf); |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
return $errbuf, unless $pcap_desc; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Set up filter, if defined |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
if ($args{FILTER} ne '') { |
132
|
|
|
|
|
|
|
return(Net::Pcap::geterr($pcap_desc)), |
133
|
|
|
|
|
|
|
if ((Net::Pcap::compile($pcap_desc, \$bpf_prog, |
134
|
|
|
|
|
|
|
$args{FILTER}, 0, $mask) == -1) || |
135
|
|
|
|
|
|
|
(Net::Pcap::setfilter($pcap_desc, $bpf_prog) == -1)); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
# Start looping |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
if ($args{mode} ne "setup") { |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Call loop function |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
my $result = Net::Pcap::loop($pcap_desc, $args{NUMPACKETS}, |
145
|
|
|
|
|
|
|
\&$callback, $args{USERDATA}); |
146
|
|
|
|
|
|
|
Net::Pcap::close($pcap_desc); |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
if ($result == 0) { |
149
|
|
|
|
|
|
|
return ""; |
150
|
|
|
|
|
|
|
} else { |
151
|
|
|
|
|
|
|
return(Net::Pcap::geterr($pcap_desc)); |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
} else { |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# Just return the pcap descriptor is setup-only mode |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
return $pcap_desc; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# Open a live network interface or save file and return the pcap |
163
|
|
|
|
|
|
|
# descriptor. Takes the same arguments as Net::PcapUtils::loop() |
164
|
|
|
|
|
|
|
# function. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub open { |
167
|
|
|
|
|
|
|
return loop(undef, @_, mode => 'setup'); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Return the next packet available on the specified packet capture |
171
|
|
|
|
|
|
|
# descriptor. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub next { |
174
|
|
|
|
|
|
|
my($pcap_t) = @_; |
175
|
|
|
|
|
|
|
my($pkt, %hdr); |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
while(!($pkt = Net::Pcap::next($pcap_t, \%hdr))) { |
178
|
|
|
|
|
|
|
# No packet available |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
return ($pkt, %hdr); |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# |
185
|
|
|
|
|
|
|
# Module initialisation |
186
|
|
|
|
|
|
|
# |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
1; |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# autoloaded methods go after the END token (&& pod) below |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
__END__ |