File Coverage

blib/lib/NetPacket/ICMP.pm
Criterion Covered Total %
statement 137 148 92.5
branch 1 2 50.0
condition 0 3 0.0
subroutine 43 47 91.4
pod 3 6 50.0
total 184 206 89.3


line stmt bran cond sub pod time code
1             package NetPacket::ICMP;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: Assemble and disassemble ICMP (Internet Control Message Protocol) packets.
4             $NetPacket::ICMP::VERSION = '1.7.2';
5 3     3   76162 use strict;
  3         14  
  3         110  
6 3     3   18 use warnings;
  3         5  
  3         111  
7              
8 3     3   465 use parent 'NetPacket';
  3         366  
  3         17  
9              
10             our @EXPORT_OK = qw(icmp_strip icmp_infotype
11             ICMP_ECHOREPLY ICMP_UNREACH ICMP_SOURCEQUENCH
12             ICMP_REDIRECT ICMP_ECHO ICMP_ROUTERADVERT
13             ICMP_ROUTERSOLICIT ICMP_TIMXCEED ICMP_PARAMPROB
14             ICMP_TSTAMP ICMP_TSTAMPREPLY ICMP_IREQ ICMP_IREQREPLY
15             ICMP_MASKREQ ICMP_MASKREPLY
16             ICMP_UNREACH_NET ICMP_UNREACH_HOST
17             ICMP_UNREACH_PROTOCOL ICMP_UNREACH_PORT
18             ICMP_UNREACH_NEEDFRAG ICMP_UNREACH_SRCFAIL
19             ICMP_UNREACH_NET_UNKNOWN ICMP_UNREACH_HOST_UNKNOWN
20             ICMP_UNREACH_ISOLATED ICMP_UNREACH_NET_PROHIB
21             ICMP_UNREACH_HOST_PROHIB ICMP_UNREACH_TOSNET
22             ICMP_UNREACH_TOSHOST ICMP_UNREACH_FILTER_PROHIB
23             ICMP_UNREACH_HOST_PRECEDENCE ICMP_UNREACH_PRCEDENCE_CUTOFF
24             ICMP_REDIRECT_NET ICMP_REDIRECT_HOST
25             ICMP_REDIRECT_TOSNET ICMP_REDIRECT_TOSHOST
26             ICMP_TIMXCEED_INTRANS ICMP_TIMXCEED_REASS
27             ICMP_PARAMPROB_OPTABSENT
28             );
29              
30             our %EXPORT_TAGS = (
31             ALL => [@EXPORT_OK],
32             types => [qw(ICMP_ECHOREPLY ICMP_UNREACH ICMP_SOURCEQUENCH
33             ICMP_REDIRECT ICMP_ECHO ICMP_ROUTERADVERT
34             ICMP_ROUTERSOLICIT ICMP_TIMXCEED ICMP_PARAMPROB
35             ICMP_TSTAMP ICMP_TSTAMPREPLY ICMP_IREQ ICMP_IREQREPLY
36             ICMP_MASKREQ ICMP_MASKREPLY)],
37             codes => [qw(ICMP_UNREACH_NET ICMP_UNREACH_HOST
38             ICMP_UNREACH_PROTOCOL ICMP_UNREACH_PORT
39             ICMP_UNREACH_NEEDFRAG ICMP_UNREACH_SRCFAIL
40             ICMP_UNREACH_NET_UNKNOWN ICMP_UNREACH_HOST_UNKNOWN
41             ICMP_UNREACH_ISOLATED ICMP_UNREACH_NET_PROHIB
42             ICMP_UNREACH_HOST_PROHIB ICMP_UNREACH_TOSNET
43             ICMP_UNREACH_TOSHOST ICMP_UNREACH_FILTER_PROHIB
44             ICMP_UNREACH_HOST_PRECEDENCE
45             ICMP_UNREACH_PRCEDENCE_CUTOFF
46             ICMP_REDIRECT_NET ICMP_REDIRECT_HOST
47             ICMP_REDIRECT_TOSNET ICMP_REDIRECT_TOSHOST
48             ICMP_TIMXCEED_INTRANS ICMP_TIMXCEED_REASS
49             ICMP_PARAMPROB_OPTABSENT)],
50             strip => [qw(icmp_strip)],
51             );
52              
53             # ICMP Types
54              
55 3     3   510 use constant ICMP_ECHOREPLY => 0;
  3         14  
  3         225  
56 3     3   18 use constant ICMP_UNREACH => 3;
  3         6  
  3         155  
57 3     3   18 use constant ICMP_SOURCEQUENCH => 4;
  3         5  
  3         151  
58 3     3   18 use constant ICMP_REDIRECT => 5;
  3         6  
  3         141  
59 3     3   18 use constant ICMP_ECHO => 8;
  3         6  
  3         135  
60 3     3   24 use constant ICMP_ROUTERADVERT => 9;
  3         9  
  3         154  
61 3     3   18 use constant ICMP_ROUTERSOLICIT => 10;
  3         5  
  3         175  
62 3     3   38 use constant ICMP_TIMXCEED => 11;
  3         6  
  3         185  
63 3     3   29 use constant ICMP_PARAMPROB => 12;
  3         7  
  3         183  
64 3     3   20 use constant ICMP_TSTAMP => 13;
  3         7  
  3         279  
65 3     3   23 use constant ICMP_TSTAMPREPLY => 14;
  3         6  
  3         152  
66 3     3   17 use constant ICMP_IREQ => 15;
  3         6  
  3         144  
67 3     3   18 use constant ICMP_IREQREPLY => 16;
  3         6  
  3         144  
68 3     3   20 use constant ICMP_MASKREQ => 17;
  3         5  
  3         138  
69 3     3   35 use constant ICMP_MASKREPLY => 18;
  3         7  
  3         172  
70              
71             # Unreachable Codes
72              
73 3     3   19 use constant ICMP_UNREACH_NET => 0;
  3         6  
  3         153  
74 3     3   17 use constant ICMP_UNREACH_HOST => 1;
  3         15  
  3         145  
75 3     3   19 use constant ICMP_UNREACH_PROTOCOL => 2;
  3         6  
  3         168  
76 3     3   18 use constant ICMP_UNREACH_PORT => 3;
  3         6  
  3         134  
77 3     3   16 use constant ICMP_UNREACH_NEEDFRAG => 4;
  3         5  
  3         156  
78 3     3   18 use constant ICMP_UNREACH_SRCFAIL => 5;
  3         6  
  3         148  
79 3     3   18 use constant ICMP_UNREACH_NET_UNKNOWN => 6;
  3         15  
  3         152  
80 3     3   18 use constant ICMP_UNREACH_HOST_UNKNOWN => 7;
  3         6  
  3         177  
81 3     3   19 use constant ICMP_UNREACH_ISOLATED => 8;
  3         5  
  3         159  
82 3     3   19 use constant ICMP_UNREACH_NET_PROHIB => 9;
  3         13  
  3         154  
83 3     3   18 use constant ICMP_UNREACH_HOST_PROHIB => 10;
  3         6  
  3         166  
84 3     3   20 use constant ICMP_UNREACH_TOSNET => 11;
  3         4  
  3         138  
85 3     3   17 use constant ICMP_UNREACH_TOSHOST => 12;
  3         6  
  3         157  
86 3     3   19 use constant ICMP_UNREACH_FILTER_PROHIB => 13;
  3         5  
  3         141  
87 3     3   18 use constant ICMP_UNREACH_HOST_PRECEDENCE => 14;
  3         5  
  3         141  
88 3     3   17 use constant ICMP_UNREACH_PRECEDENCE_CUTOFF => 15;
  3         5  
  3         165  
89              
90             # Redirect Codes
91              
92 3     3   41 use constant ICMP_REDIRECT_NET => 0;
  3         6  
  3         152  
93 3     3   18 use constant ICMP_REDIRECT_HOST => 1;
  3         5  
  3         170  
94 3     3   64 use constant ICMP_REDIRECT_TOSNET => 2;
  3         7  
  3         687  
95 3     3   19 use constant ICMP_REDIRECT_TOSHOST => 3;
  3         5  
  3         139  
96              
97             # Time-Exceeded Codes
98              
99 3     3   17 use constant ICMP_TIMXCEED_INTRANS => 0;
  3         5  
  3         156  
100 3     3   18 use constant ICMP_TIMXCEED_REASS => 1;
  3         13  
  3         190  
101              
102             # Parameter-Problem Codes
103              
104 3     3   20 use constant ICMP_PARAMPROB_OPTABSENT => 1;
  3         5  
  3         1576  
105              
106             #
107             # Test for informational types
108             #
109              
110             sub icmp_infotype {
111 0     0 0 0 my $type = shift;
112 0   0     0 return ($type == ICMP_ECHOREPLY || $type == ICMP_ECHO ||
113             $type == ICMP_ROUTERADVERT || $type == ICMP_ROUTERSOLICIT ||
114             $type == ICMP_TSTAMP || $type == ICMP_TSTAMPREPLY ||
115             $type == ICMP_IREQ || $type == ICMP_IREQREPLY ||
116             $type == ICMP_MASKREQ || $type == ICMP_MASKREPLY);
117             }
118              
119             #
120             # Decode the packet
121             #
122              
123             sub decode {
124 1     1 1 12 my $class = shift;
125 1         2 my($pkt, $parent) = @_;
126 1         2 my $self = {};
127              
128             # Class fields
129              
130 1         4 $self->{_parent} = $parent;
131 1         3 $self->{_frame} = $pkt;
132              
133             # Decode ICMP packet
134              
135 1 50       3 if (defined($pkt)) {
136              
137 1         5 ($self->{type}, $self->{code}, $self->{cksum}, $self->{data}) =
138             unpack("CCna*", $pkt);
139             }
140              
141             # Return a blessed object
142              
143 1         3 bless($self, $class);
144 1         2 return $self;
145             }
146              
147             #
148             # Strip a packet of its header and return the data
149             #
150              
151             sub icmpstrip {
152 0     0 0 0 goto \&strip;
153             }
154              
155             sub strip {
156 0     0 1 0 my ($pkt) = @_;
157              
158 0         0 my $icmp_obj = decode($pkt);
159 0         0 return $icmp_obj->{data};
160             }
161              
162             #
163             # Encode a packet
164             #
165              
166             sub encode {
167 0     0 1 0 my $self = shift;
168 0         0 my ($packet);
169              
170             # Checksum the packet
171 0         0 $self->checksum();
172              
173             # Put the packet together
174             $packet = pack("CCna*", $self->{type}, $self->{code},
175 0         0 $self->{cksum}, $self->{data});
176              
177 0         0 return($packet);
178             }
179              
180             #
181             # Calculate ICMP checksum
182              
183             sub checksum {
184 1     1 0 828 my $self = shift;
185 1         3 my ($packet,$zero);
186              
187             # Put the packet together for checksumming
188 1         3 $zero = 0;
189             $packet = pack("CCna*", $self->{type}, $self->{code},
190 1         10 $zero, $self->{data});
191              
192 1         5 $self->{cksum} = NetPacket::htons(NetPacket::in_cksum($packet));
193             }
194              
195              
196             #
197             # Module initialisation
198             #
199              
200             1;
201              
202             # autoloaded methods go after the END token (&& pod) below
203              
204             =pod
205              
206             =head1 NAME
207              
208             NetPacket::ICMP - Assemble and disassemble ICMP (Internet Control Message Protocol) packets.
209              
210             =head1 VERSION
211              
212             version 1.7.2
213              
214             =head1 SYNOPSIS
215              
216             use NetPacket::ICMP;
217              
218             $icmp_obj = NetPacket::ICMP->decode($raw_pkt);
219             $icmp_pkt = NetPacket::ICMP->encode();
220             $icmp_data = NetPacket::ICMP::strip($raw_pkt);
221              
222             =head1 DESCRIPTION
223              
224             C provides a set of routines for assembling and
225             disassembling packets using ICMP (Internet Control Message Protocol).
226              
227             =head2 Methods
228              
229             =over
230              
231             =item Cdecode([RAW PACKET])>
232              
233             Decode the raw packet data given and return an object containing
234             instance data. This method will quite happily decode garbage input.
235             It is the responsibility of the programmer to ensure valid packet data
236             is passed to this method.
237              
238             =item Cencode()>
239              
240             Return an ICMP packet encoded with the instance data specified.
241              
242             =back
243              
244             =head2 Functions
245              
246             =over
247              
248             =item C
249              
250             Return the encapsulated data (or payload) contained in the ICMP
251             packet.
252              
253             =back
254              
255             =head2 Instance data
256              
257             The instance data for the C object consists of
258             the following fields.
259              
260             =over
261              
262             =item type
263              
264             The ICMP message type of this packet.
265              
266             =item code
267              
268             The ICMP message code of this packet.
269              
270             =item cksum
271              
272             The checksum for this packet.
273              
274             =item data
275              
276             The encapsulated data (payload) for this packet.
277              
278             =back
279              
280             =head2 Exports
281              
282             =over
283              
284             =item default
285              
286             none
287              
288             =item exportable
289              
290             ICMP message types:
291             ICMP_ECHOREPLY ICMP_UNREACH ICMP_SOURCEQUENCH
292             ICMP_REDIRECT ICMP_ECHO ICMP_ROUTERADVERT
293             ICMP_ROUTERSOLICIT ICMP_TIMXCEED ICMP_PARAMPROB
294             ICMP_TSTAMP ICMP_TSTAMPREPLY ICMP_IREQ ICMP_IREQREPLY
295             ICMP_MASKREQ ICMP_MASKREPLY
296              
297             =item tags
298              
299             The following tags group together related exportable items.
300              
301             =over
302              
303             =item C<:types>
304              
305             ICMP_ECHOREPLY ICMP_UNREACH ICMP_SOURCEQUENCH
306             ICMP_REDIRECT ICMP_ECHO ICMP_ROUTERADVERT
307             ICMP_ROUTERSOLICIT ICMP_TIMXCEED ICMP_PARAMPROB
308             ICMP_TSTAMP ICMP_TSTAMPREPLY ICMP_IREQ
309             ICMP_IREQREPLY ICMP_MASKREQ ICMP_MASKREPLY
310              
311             =item C<:strip>
312              
313             Import the strip function C.
314              
315             =item C<:ALL>
316              
317             All the above exportable items.
318              
319             =back
320              
321             =back
322              
323             =head1 EXAMPLE
324              
325             The following example prints the ICMP type, code, and checksum
326             fields.
327              
328             #!/usr/bin/perl -w
329              
330             use strict;
331             use Net::PcapUtils;
332             use NetPacket::Ethernet qw(:strip);
333             use NetPacket::IP qw(:strip);
334             use NetPacket::ICMP;
335              
336             sub process_pkt {
337             my ($user, $hdr, $pkt) = @_;
338              
339             my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
340             my $icmp_obj = NetPacket::ICMP->decode(ip_strip($ip_obj));
341              
342             print("Type: $icmp_obj->{type}\n");
343             print("Code: $icmp_obj->{code}\n");
344             print("Checksum: $icmp_obj->{cksum}\n\n");
345             }
346              
347             Net::PcapUtils::loop(\&process_pkt, FILTER => 'icmp');
348              
349             =head1 TODO
350              
351             =over
352              
353             =item Create constants
354              
355             =back
356              
357             =head1 COPYRIGHT
358              
359             Copyright (c) 2001 Tim Potter and Stephanie Wehner.
360              
361             Copyright (c) 1995,1996,1997,1998,1999 ANU and CSIRO on behalf of
362             the participants in the CRC for Advanced Computational Systems
363             ('ACSys').
364              
365             This module is free software. You can redistribute it and/or
366             modify it under the terms of the Artistic License 2.0.
367              
368             This program is distributed in the hope that it will be useful,
369             but without any warranty; without even the implied warranty of
370             merchantability or fitness for a particular purpose.
371              
372             =head1 AUTHOR
373              
374             Tim Potter Etpot@samba.orgE
375              
376             Stephanie Wehner Eatrak@itsx.comE
377              
378             =cut
379              
380             __END__