File Coverage

blib/lib/NetPacket/ICMP.pm
Criterion Covered Total %
statement 139 150 92.6
branch 1 2 50.0
condition 0 3 0.0
subroutine 44 47 93.6
pod 3 5 60.0
total 187 207 90.3


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