File Coverage

blib/lib/NetPacket/IP.pm
Criterion Covered Total %
statement 98 102 96.0
branch 5 10 50.0
condition n/a
subroutine 19 20 95.0
pod 3 4 75.0
total 125 136 91.9


line stmt bran cond sub pod time code
1             #
2             # NetPacket::IP - Decode and encode IP (Internet Protocol) packets.
3             #
4             # Encoding part by Stephanie Wehner, atrak@itsx.com
5              
6             package NetPacket::IP;
7             BEGIN {
8 8     8   43661 $NetPacket::IP::AUTHORITY = 'cpan:YANICK';
9             }
10             # ABSTRACT: Assemble and disassemble IP (Internet Protocol) packets.
11             $NetPacket::IP::VERSION = '1.5.0';
12 8     8   61 use strict;
  8         16  
  8         349  
13 8     8   39 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  8         12  
  8         580  
14 8     8   3359 use NetPacket;
  8         18  
  8         985  
15              
16             BEGIN {
17 8     8   133 @ISA = qw(Exporter NetPacket);
18              
19             # Items to export into callers namespace by default
20             # (move infrequently used names to @EXPORT_OK below)
21              
22 8         20 @EXPORT = qw(
23             );
24              
25             # Other items we are prepared to export if requested
26              
27 8         55 @EXPORT_OK = qw(ip_strip
28             IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP
29             IP_PROTO_IPIP IP_PROTO_TCP IP_PROTO_UDP
30             IP_VERSION_IPv4
31             IP_FLAG_MOREFRAGS IP_FLAG_DONTFRAG IP_FLAG_CONGESTION
32             IP_MAXPACKET
33             );
34              
35             # Tags:
36              
37 8         245 %EXPORT_TAGS = (
38             ALL => [@EXPORT, @EXPORT_OK],
39             protos => [qw(IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP IP_PROTO_IPIP
40             IP_PROTO_TCP IP_PROTO_UDP)],
41             versions => [qw(IP_VERSION_IPv4)],
42             strip => [qw(ip_strip)],
43             flags => [qw(IP_FLAG_MOREFRAGS IP_FLAG_DONTFRAG IP_FLAG_CONGESTION)],
44             );
45              
46             }
47              
48             #
49             # Partial list of IP protocol values from RFC 1700
50             #
51              
52 8     8   56 use constant IP_PROTO_IP => 0; # Dummy protocol for TCP
  8         13  
  8         539  
53 8     8   44 use constant IP_PROTO_ICMP => 1; # Internet Control Message Protocol
  8         11  
  8         362  
54 8     8   109 use constant IP_PROTO_IGMP => 2; # Internet Group Management Protocol
  8         44  
  8         436  
55 8     8   37 use constant IP_PROTO_IPIP => 4; # IP in IP encapsulation
  8         19  
  8         386  
56 8     8   44 use constant IP_PROTO_TCP => 6; # Transmission Control Protocol
  8         27  
  8         506  
57 8     8   39 use constant IP_PROTO_UDP => 17; # User Datagram Protocol
  8         29  
  8         356  
58              
59             #
60             # Partial list of IP version numbers from RFC 1700
61             #
62              
63 8     8   46 use constant IP_VERSION_IPv4 => 4; # IP version 4
  8         13  
  8         424  
64              
65             #
66             # Flag values
67             #
68              
69 8     8   38 use constant IP_FLAG_MOREFRAGS => 1; # More fragments coming
  8         17  
  8         342  
70 8     8   71 use constant IP_FLAG_DONTFRAG => 2; # Don't fragment me
  8         13  
  8         322  
71 8     8   44 use constant IP_FLAG_CONGESTION => 4; # Congestion present
  8         14  
  8         331  
72              
73             # Maximum IP Packet size
74 8     8   672 use constant IP_MAXPACKET => 65535;
  8         26  
  8         13602  
75              
76             # Convert 32-bit IP address to dotted quad notation
77              
78             sub to_dotquad {
79 16     16 0 29 my($net) = @_ ;
80 16         23 my($na, $nb, $nc, $nd);
81              
82 16         27 $na = $net >> 24 & 255;
83 16         25 $nb = $net >> 16 & 255;
84 16         21 $nc = $net >> 8 & 255;
85 16         25 $nd = $net & 255;
86              
87 16         178 return ("$na.$nb.$nc.$nd");
88             }
89              
90             #
91             # Decode the packet
92             #
93              
94             sub decode {
95 8     8 1 1062 my $class = shift;
96 8         20 my($pkt, $parent) = @_;
97 8         17 my $self = {};
98              
99             # Class fields
100              
101 8         19 $self->{_parent} = $parent;
102 8         77 $self->{_frame} = $pkt;
103              
104             # Decode IP packet
105              
106 8 50       32 if (defined($pkt)) {
107 8         15 my $tmp;
108              
109 8         108 ($tmp, $self->{tos},$self->{len}, $self->{id}, $self->{foffset},
110             $self->{ttl}, $self->{proto}, $self->{cksum}, $self->{src_ip},
111             $self->{dest_ip}, $self->{options}) = unpack('CCnnnCCnNNa*' , $pkt);
112              
113             # Extract bit fields
114            
115 8         31 $self->{ver} = ($tmp & 0xf0) >> 4;
116 8         20 $self->{hlen} = $tmp & 0x0f;
117            
118 8         23 $self->{flags} = $self->{foffset} >> 13;
119 8         19 $self->{foffset} = ($self->{foffset} & 0x1fff) << 3;
120              
121             # Decode variable length header options and remaining data in field
122              
123 8         19 my $olen = $self->{hlen} - 5;
124 8 50       41 $olen = 0 if $olen < 0; # Check for bad hlen
125              
126             # Option length is number of 32 bit words
127              
128 8         20 $olen = $olen * 4;
129              
130 8         94 ($self->{options}, $self->{data}) = unpack("a" . $olen .
131             "a*", $self->{options});
132              
133 8         22 my $length = $self->{hlen};
134 8 50       40 $length = 5 if $length < 5; # precaution against bad header
135              
136             # truncate data to the length given by the header
137 8         32 $self->{data} = substr $self->{data}, 0, $self->{len} - 4 * $length;
138              
139             # Convert 32 bit ip addresses to dotted quad notation
140              
141 8         28 $self->{src_ip} = to_dotquad($self->{src_ip});
142 8         29 $self->{dest_ip} = to_dotquad($self->{dest_ip});
143             }
144              
145 8         34 return bless $self, $class;
146             }
147              
148             #
149             # Strip header from packet and return the data contained in it
150             #
151              
152             undef &ip_strip; # Create ip_strip alias
153             *ip_strip = \&strip;
154              
155             sub strip {
156 0     0 1 0 my ($pkt) = @_;
157              
158 0         0 my $ip_obj = NetPacket::IP->decode($pkt);
159 0         0 return $ip_obj->{data};
160             }
161              
162             #
163             # Encode a packet
164             #
165              
166             sub encode {
167              
168 1     1 1 906 my $self = shift;
169 1         3 my ($hdr,$packet,$zero,$tmp,$offset);
170 0         0 my ($src_ip, $dest_ip);
171              
172             # create a zero variable
173 1         2 $zero = 0;
174              
175             # adjust the length of the packet
176 1         5 $self->{len} = ($self->{hlen} * 4) + length($self->{data});
177              
178 1         2 $tmp = $self->{hlen} & 0x0f;
179 1         4 $tmp = $tmp | (($self->{ver} << 4) & 0xf0);
180              
181 1         2 $offset = $self->{flags} << 13;
182 1         3 $offset = $offset | (($self->{foffset} >> 3) & 0x1fff);
183              
184             # convert the src and dst ip
185 1         162 $src_ip = gethostbyname($self->{src_ip});
186 1         69 $dest_ip = gethostbyname($self->{dest_ip});
187              
188 1         3 my $fmt = 'CCnnnCCna4a4a*';
189 1         7 my @pkt = ($tmp, $self->{tos},$self->{len},
190             $self->{id}, $offset, $self->{ttl}, $self->{proto},
191             $zero, $src_ip, $dest_ip);
192             # change format and package in case of IP options
193 1 50       5 if(defined $self->{options}){
194 1         3 $fmt = 'CCnnnCCna4a4a*a*';
195 1         4 push(@pkt, $self->{options});
196             }
197              
198             # construct header to calculate the checksum
199 1         9 $hdr = pack($fmt, @pkt);
200 1         7 $self->{cksum} = NetPacket::htons(NetPacket::in_cksum($hdr));
201 1         2 $pkt[7] = $self->{cksum};
202              
203             # make the entire packet
204 1 50       4 if(defined $self->{data}){
205 1         3 push(@pkt, $self->{data});
206             }
207 1         5 $packet = pack($fmt, @pkt);
208              
209 1         6 return($packet);
210             }
211              
212             #
213             # Module initialisation
214             #
215              
216             1;
217              
218             # autoloaded methods go after the END token (&& pod) below
219              
220             =pod
221              
222             =head1 NAME
223              
224             NetPacket::IP - Assemble and disassemble IP (Internet Protocol) packets.
225              
226             =head1 VERSION
227              
228             version 1.5.0
229              
230             =head1 SYNOPSIS
231              
232             use NetPacket::IP;
233              
234             $ip_obj = NetPacket::IP->decode($raw_pkt);
235             $ip_pkt = NetPacket::IP->encode($ip_obj);
236             $ip_data = NetPacket::IP::strip($raw_pkt);
237              
238             =head1 DESCRIPTION
239              
240             C provides a set of routines for assembling and
241             disassembling packets using IP (Internet Protocol).
242              
243             =head2 Methods
244              
245             =over
246              
247             =item Cdecode([RAW PACKET])>
248              
249             Decode the raw packet data given and return an object containing
250             instance data. This method will quite happily decode garbage input.
251             It is the responsibility of the programmer to ensure valid packet data
252             is passed to this method.
253              
254             =item Cencode()>
255              
256             Return an IP packet encoded with the instance data specified. This
257             will infer the total length of the packet automatically from the
258             payload length and also adjust the checksum.
259              
260             =back
261              
262             =head2 Functions
263              
264             =over
265              
266             =item C
267              
268             Return the encapsulated data (or payload) contained in the IP
269             packet. This data is suitable to be used as input for other
270             C modules.
271              
272             This function is equivalent to creating an object using the
273             C constructor and returning the C field of that
274             object.
275              
276             =back
277              
278             =head2 Instance data
279              
280             The instance data for the C object consists of
281             the following fields.
282              
283             =over
284              
285             =item ver
286              
287             The IP version number of this packet.
288              
289             =item hlen
290              
291             The IP header length of this packet.
292              
293             =item flags
294              
295             The IP header flags for this packet.
296              
297             =item foffset
298              
299             The IP fragment offset for this packet.
300              
301             =item tos
302              
303             The type-of-service for this IP packet.
304              
305             =item len
306              
307             The length (including length of header) in bytes for this packet.
308              
309             =item id
310              
311             The identification (sequence) number for this IP packet.
312              
313             =item ttl
314              
315             The time-to-live value for this packet.
316              
317             =item proto
318              
319             The IP protocol number for this packet.
320              
321             =item cksum
322              
323             The IP checksum value for this packet.
324              
325             =item src_ip
326              
327             The source IP address for this packet in dotted-quad notation.
328              
329             =item dest_ip
330              
331             The destination IP address for this packet in dotted-quad notation.
332              
333             =item options
334              
335             Any IP options for this packet.
336              
337             =item data
338              
339             The encapsulated data (payload) for this IP packet.
340              
341             =back
342              
343             =head2 Exports
344              
345             =over
346              
347             =item default
348              
349             none
350              
351             =item exportable
352              
353             IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP IP_PROTO_IPIP IP_PROTO_TCP
354             IP_PROTO_UDP IP_VERSION_IPv4
355              
356             =item tags
357              
358             The following tags group together related exportable items.
359              
360             =over
361              
362             =item C<:protos>
363              
364             IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP IP_PROTO_IPIP
365             IP_PROTO_TCP IP_PROTO_UDP
366              
367             =item C<:versions>
368              
369             IP_VERSION_IPv4
370              
371             =item C<:strip>
372              
373             Import the strip function C.
374              
375             =item C<:ALL>
376              
377             All the above exportable items.
378              
379             =back
380              
381             =back
382              
383             =head1 EXAMPLE
384              
385             The following script dumps IP frames by IP address and protocol
386             to standard output.
387              
388             #!/usr/bin/perl -w
389              
390             use strict;
391             use Net::PcapUtils;
392             use NetPacket::Ethernet qw(:strip);
393             use NetPacket::IP;
394              
395             sub process_pkt {
396             my ($user, $hdr, $pkt) = @_;
397              
398             my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
399             print("$ip_obj->{src_ip}:$ip_obj->{dest_ip} $ip_obj->{proto}\n");
400             }
401              
402             Net::PcapUtils::loop(\&process_pkt, FILTER => 'ip');
403              
404             =head1 TODO
405              
406             =over
407              
408             =item IP option decoding - currently stored in binary form.
409              
410             =item Assembly of received fragments
411              
412             =back
413              
414             =head1 COPYRIGHT
415              
416             Copyright (c) 2001 Tim Potter and Stephanie Wehner.
417              
418             Copyright (c) 1995,1996,1997,1998,1999 ANU and CSIRO on behalf of
419             the participants in the CRC for Advanced Computational Systems
420             ('ACSys').
421              
422             This module is free software. You can redistribute it and/or
423             modify it under the terms of the Artistic License 2.0.
424              
425             This program is distributed in the hope that it will be useful,
426             but without any warranty; without even the implied warranty of
427             merchantability or fitness for a particular purpose.
428              
429             =head1 AUTHOR
430              
431             Tim Potter Etpot@samba.orgE
432              
433             Stephanie Wehner Eatrak@itsx.comE
434              
435             =cut
436              
437             __END__