1package NetPacket::IP;
2BEGIN {
3  $NetPacket::IP::AUTHORITY = 'cpan:YANICK';
4}
5# ABSTRACT: Assemble and disassemble IP (Internet Protocol) packets.
6$NetPacket::IP::VERSION = '1.6.0';
7use strict;
8use warnings;
9
10use parent 'NetPacket';
11
12our @EXPORT_OK = qw(ip_strip
13		    IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP
14		    IP_PROTO_IPIP IP_PROTO_TCP IP_PROTO_EGP
15		    IP_PROTO_EGP IP_PROTO_PUP IP_PROTO_UDP
16		    IP_PROTO_IDP IP_PROTO_TP IP_PROTO_DCCP
17		    IP_PROTO_IPV6 IP_PROTO_ROUTING IP_PROTO_FRAGMENT
18		    IP_PROTO_RSVP IP_PROTO_GRE IP_PROTO_ESP
19		    IP_PROTO_AH IP_PROTO_ICMPV6 IP_PROTO_NONE
20		    IP_PROTO_DSTOPTS IP_PROTO_MTP IP_PROTO_ENCAP
21		    IP_PROTO_PIM IP_PROTO_COMP IP_PROTO_SCTP
22		    IP_PROTO_UDPLITE
23		    IP_VERSION_IPv4
24		    IP_FLAG_MOREFRAGS IP_FLAG_DONTFRAG IP_FLAG_CONGESTION
25		    IPTOS_ECN_MASK IPTOS_ECN_NOT_ECT IPTOS_ECN_ECT1
26		    IPTOS_ECN_ECT0 IPTOS_ECN_CE
27		    IPTOS_DSCP_MASK IPTOS_DSCP_EF
28		    IPTOS_DSCP_AF11 IPTOS_DSCP_AF12 IPTOS_DSCP_AF13
29		    IPTOS_DSCP_AF21 IPTOS_DSCP_AF22 IPTOS_DSCP_AF23
30		    IPTOS_DSCP_AF31 IPTOS_DSCP_AF32 IPTOS_DSCP_AF33
31		    IPTOS_DSCP_AF41 IPTOS_DSCP_AF42 IPTOS_DSCP_AF43
32		    IPTOS_CLASS_MASK IPTOS_CLASS_DEFAULT
33		    IPTOS_CLASS_CS0 IPTOS_CLASS_CS1 IPTOS_CLASS_CS2
34		    IPTOS_CLASS_CS3 IPTOS_CLASS_CS4 IPTOS_CLASS_CS5
35		    IPTOS_CLASS_CS6 IPTOS_CLASS_CS7
36		    IPTOS_PREC_MASK IPTOS_PREC_NETCONTROL
37		    IPTOS_PREC_INTERNETCONTROL IPTOS_PREC_CRITIC_ECP
38		    IPTOS_PREC_FLASHOVERRIDE IPTOS_PREC_FLASH
39		    IPTOS_PREC_IMMEDIATE IPTOS_PREC_PRIORITY
40		    IPTOS_PREC_ROUTINE
41                    MAXTTL IPDEFTTL IPFRAGTTL IPTTLDEC IP_MSS IP_MAXPACKET
42    );
43
44our %EXPORT_TAGS = (
45    ALL         => [@EXPORT_OK],
46    protos      => [qw(IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP IP_PROTO_IPIP
47		       IP_PROTO_TCP IP_PROTO_EGP IP_PROTO_PUP
48		       IP_PROTO_UDP IP_PROTO_IDP IP_PROTO_TP IP_PROTO_DCCP
49		       IP_PROTO_IPV6 IP_PROTO_ROUTING IP_PROTO_FRAGMENT
50		       IP_PROTO_RSVP IP_PROTO_GRE IP_PROTO_ESP IP_PROTO_AH
51		       IP_PROTO_ICMPV6 IP_PROTO_NONE IP_PROTO_DSTOPTS
52		       IP_PROTO_MTP IP_PROTO_ENCAP IP_PROTO_PIM IP_PROTO_COMP
53		       IP_PROTO_SCTP IP_PROTO_UDPLITE)],
54    versions    => [qw(IP_VERSION_IPv4)],
55    strip       => [qw(ip_strip)],
56    flags       => [qw(IP_FLAG_MOREFRAGS IP_FLAG_DONTFRAG IP_FLAG_CONGESTION)],
57    tos         => [qw(IPTOS_ECN_MASK IPTOS_ECN_NOT_ECT IPTOS_ECN_ECT1
58		       IPTOS_ECN_ECT0 IPTOS_ECN_CE
59		       IPTOS_DSCP_MASK IPTOS_DSCP_EF
60		       IPTOS_DSCP_AF11 IPTOS_DSCP_AF12 IPTOS_DSCP_AF13
61		       IPTOS_DSCP_AF21 IPTOS_DSCP_AF22 IPTOS_DSCP_AF23
62		       IPTOS_DSCP_AF31 IPTOS_DSCP_AF32 IPTOS_DSCP_AF33
63		       IPTOS_DSCP_AF41 IPTOS_DSCP_AF42 IPTOS_DSCP_AF43
64		       IPTOS_CLASS_MASK IPTOS_CLASS_DEFAULT
65		       IPTOS_CLASS_CS0 IPTOS_CLASS_CS1 IPTOS_CLASS_CS2
66		       IPTOS_CLASS_CS3 IPTOS_CLASS_CS4 IPTOS_CLASS_CS5
67		       IPTOS_CLASS_CS6 IPTOS_CLASS_CS7
68		       IPTOS_PREC_MASK IPTOS_PREC_NETCONTROL
69		       IPTOS_PREC_INTERNETCONTROL IPTOS_PREC_CRITIC_ECP
70		       IPTOS_PREC_FLASHOVERRIDE IPTOS_PREC_FLASH
71		       IPTOS_PREC_IMMEDIATE IPTOS_PREC_PRIORITY
72		       IPTOS_PREC_ROUTINE)],
73    misc        => [qw(MAXTTL IPDEFTTL IPFRAGTTL IPTTLDEC IP_MSS
74                       IP_MAXPACKET)],
75    );
76
77#
78# Partial list of IP protocol values from RFC 1700
79#
80
81use constant IP_PROTO_IP   => 0;       # Dummy protocol for TCP
82use constant IP_PROTO_ICMP => 1;       # Internet Control Message Protocol
83use constant IP_PROTO_IGMP => 2;       # Internet Group Management Protocol
84use constant IP_PROTO_IPIP => 4;       # IP in IP encapsulation
85use constant IP_PROTO_TCP  => 6;       # Transmission Control Protocol
86use constant IP_PROTO_EGP  => 8;       # Exterior Gateway Protocol
87use constant IP_PROTO_PUP  => 12;      # PUP protocol
88use constant IP_PROTO_UDP  => 17;      # User Datagram Protocol
89use constant IP_PROTO_IDP  => 22;      # XNS IDP Protocol
90use constant IP_PROTO_TP   => 29;      # SO Transport Protocol Class 4
91use constant IP_PROTO_DCCP => 33;      # Datagram Congestion Control Protocol
92use constant IP_PROTO_IPV6 => 41;      # IPv6 header
93use constant IP_PROTO_ROUTING => 43;   # IPv6 routing header
94use constant IP_PROTO_FRAGMENT => 44;  # IPv6 fragmentation header
95use constant IP_PROTO_RSVP => 46;      # Reservation Protocol
96use constant IP_PROTO_GRE  => 47;      # General Routing Encapsulation
97use constant IP_PROTO_ESP  => 50;      # encapsulating security payload
98use constant IP_PROTO_AH   => 51;      # authentication header
99use constant IP_PROTO_ICMPV6 => 58;    # ICMPv6
100use constant IP_PROTO_NONE => 59;      # IPv6 no next header
101use constant IP_PROTO_DSTOPTS => 60;   # IPv6 destination options
102use constant IP_PROTO_MTP => 92;       # Multicast Transport Protocol
103use constant IP_PROTO_ENCAP => 98;     # Encapsulation Header
104use constant IP_PROTO_PIM => 103;      # Protocol Independent Multicast
105use constant IP_PROTO_COMP => 108;     # Compression Header Protocol
106use constant IP_PROTO_SCTP => 132;     # Stream Control Transmission Protocol
107use constant IP_PROTO_UDPLITE => 136;  # UDP-Lite protocol
108
109
110#
111# Partial list of IP version numbers from RFC 1700
112#
113
114use constant IP_VERSION_IPv4 => 4;     # IP version 4
115
116#
117# Flag values
118#
119
120use constant IP_FLAG_MOREFRAGS  => 1;     # More fragments coming
121use constant IP_FLAG_DONTFRAG   => 2;     # Don't fragment me
122use constant IP_FLAG_CONGESTION => 4;     # Congestion present
123
124#
125# ToS/DSCP values
126#
127
128use constant IPTOS_ECN_MASK     => 0x03;
129use constant IPTOS_ECN_NOT_ECT  => 0x00;
130use constant IPTOS_ECN_ECT1     => 0x01;
131use constant IPTOS_ECN_ECT0     => 0x02;
132use constant IPTOS_ECN_CE       => 0x03;
133
134use constant IPTOS_DSCP_MASK    => 0xfc;
135use constant IPTOS_DSCP_AF11    => 0x28;
136use constant IPTOS_DSCP_AF12    => 0x30;
137use constant IPTOS_DSCP_AF13    => 0x38;
138use constant IPTOS_DSCP_AF21    => 0x48;
139use constant IPTOS_DSCP_AF22    => 0x50;
140use constant IPTOS_DSCP_AF23    => 0x58;
141use constant IPTOS_DSCP_AF31    => 0x68;
142use constant IPTOS_DSCP_AF32    => 0x70;
143use constant IPTOS_DSCP_AF33    => 0x78;
144use constant IPTOS_DSCP_AF41    => 0x88;
145use constant IPTOS_DSCP_AF42    => 0x90;
146use constant IPTOS_DSCP_AF43    => 0x98;
147use constant IPTOS_DSCP_EF      => 0xb8;
148
149use constant IPTOS_CLASS_MASK   => 0xe0;
150use constant IPTOS_CLASS_CS0    => 0x00;
151use constant IPTOS_CLASS_CS1    => 0x20;
152use constant IPTOS_CLASS_CS2    => 0x40;
153use constant IPTOS_CLASS_CS3    => 0x60;
154use constant IPTOS_CLASS_CS4    => 0x80;
155use constant IPTOS_CLASS_CS5    => 0xa0;
156use constant IPTOS_CLASS_CS6    => 0xc0;
157use constant IPTOS_CLASS_CS7    => 0xe0;
158use constant IPTOS_CLASS_DEFAULT => 0x00;
159
160use constant IPTOS_PREC_MASK    => 0xe0;
161use constant IPTOS_PREC_NETCONTROL => 0xe0;
162use constant IPTOS_PREC_INTERNETCONTROL => 0xc0;
163use constant IPTOS_PREC_CRITIC_ECP => 0x0a;
164use constant IPTOS_PREC_FLASHOVERRIDE => 0x80;
165use constant IPTOS_PREC_FLASH   => 0x60;
166use constant IPTOS_PREC_IMMEDIATE => 0x40;
167use constant IPTOS_PREC_PRIORITY => 0x20;
168use constant IPTOS_PREC_ROUTINE => 0x00;
169
170# TTL values
171use constant MAXTTL             => 255;
172use constant IPDEFTTL           => 64;
173use constant IPFRAGTTL          => 60;
174use constant IPTTLDEC           => 1;
175
176use constant IP_MSS             => 576;
177
178# Maximum IP Packet size
179use constant IP_MAXPACKET => 65535;
180
181# Convert 32-bit IP address to dotted quad notation
182
183sub to_dotquad {
184    my($net) = @_ ;
185    my($na, $nb, $nc, $nd);
186
187    $na = $net >> 24 & 255;
188    $nb = $net >> 16 & 255;
189    $nc = $net >>  8 & 255;
190    $nd = $net & 255;
191
192    return ("$na.$nb.$nc.$nd");
193}
194
195#
196# Decode the packet
197#
198
199sub decode {
200    my $class = shift;
201    my($pkt, $parent) = @_;
202    my $self = {};
203
204    # Class fields
205
206    $self->{_parent} = $parent;
207    $self->{_frame} = $pkt;
208
209    # Decode IP packet
210
211    if (defined($pkt)) {
212	my $tmp;
213
214	($tmp, $self->{tos},$self->{len}, $self->{id}, $self->{foffset},
215	 $self->{ttl}, $self->{proto}, $self->{cksum}, $self->{src_ip},
216	 $self->{dest_ip}, $self->{options}) = unpack('CCnnnCCnNNa*' , $pkt);
217
218	# Extract bit fields
219
220	$self->{ver} = ($tmp & 0xf0) >> 4;
221	$self->{hlen} = $tmp & 0x0f;
222
223	$self->{flags} = $self->{foffset} >> 13;
224	$self->{foffset} = ($self->{foffset} & 0x1fff) << 3;
225
226	# Decode variable length header options and remaining data in field
227
228	my $olen = $self->{hlen} - 5;
229	$olen = 0 if $olen < 0;  # Check for bad hlen
230
231	# Option length is number of 32 bit words
232
233        $olen = $olen * 4;
234
235	($self->{options}, $self->{data}) = unpack("a" . $olen .
236						   "a*", $self->{options});
237
238    my $length = $self->{hlen};
239    $length = 5 if $length < 5;  # precaution against bad header
240
241    # truncate data to the length given by the header
242    $self->{data} = substr $self->{data}, 0, $self->{len} - 4 * $length;
243
244	# Convert 32 bit ip addresses to dotted quad notation
245
246	$self->{src_ip} = to_dotquad($self->{src_ip});
247	$self->{dest_ip} = to_dotquad($self->{dest_ip});
248    }
249
250    return bless $self, $class;
251}
252
253#
254# Strip header from packet and return the data contained in it
255#
256
257undef &ip_strip;           # Create ip_strip alias
258*ip_strip = \&strip;
259
260sub strip {
261    my ($pkt) = @_;
262
263    my $ip_obj = NetPacket::IP->decode($pkt);
264    return $ip_obj->{data};
265}
266
267#
268# Encode a packet
269#
270
271sub encode {
272
273    my $self = shift;
274    my ($hdr,$packet,$zero,$tmp,$offset);
275    my ($src_ip, $dest_ip);
276
277    # create a zero variable
278    $zero = 0;
279
280    # adjust the length of the packet
281    $self->{len} = ($self->{hlen} * 4) + length($self->{data});
282
283    $tmp = $self->{hlen} & 0x0f;
284    $tmp = $tmp | (($self->{ver} << 4) & 0xf0);
285
286    $offset = $self->{flags} << 13;
287    $offset = $offset | (($self->{foffset} >> 3) & 0x1fff);
288
289    # convert the src and dst ip
290    $src_ip = gethostbyname($self->{src_ip});
291    $dest_ip = gethostbyname($self->{dest_ip});
292
293    my $fmt = 'CCnnnCCna4a4a*';
294    my @pkt = ($tmp, $self->{tos},$self->{len},
295               $self->{id}, $offset, $self->{ttl}, $self->{proto},
296               $zero, $src_ip, $dest_ip);
297    # change format and package in case of IP options
298    if(defined $self->{options}){
299        $fmt = 'CCnnnCCna4a4a*a*';
300        push(@pkt, $self->{options});
301    }
302
303    # construct header to calculate the checksum
304    $hdr = pack($fmt, @pkt);
305    $self->{cksum} = NetPacket::htons(NetPacket::in_cksum($hdr));
306    $pkt[7] = $self->{cksum};
307
308    # make the entire packet
309    if(defined $self->{data}){
310        push(@pkt, $self->{data});
311    }
312    $packet = pack($fmt, @pkt);
313
314    return($packet);
315}
316
317#
318# Module initialisation
319#
320
3211;
322
323# autoloaded methods go after the END token (&& pod) below
324
325=pod
326
327=head1 NAME
328
329NetPacket::IP - Assemble and disassemble IP (Internet Protocol) packets.
330
331=head1 VERSION
332
333version 1.6.0
334
335=head1 SYNOPSIS
336
337  use NetPacket::IP;
338
339  $ip_obj = NetPacket::IP->decode($raw_pkt);
340  $ip_pkt = NetPacket::IP->encode($ip_obj);
341  $ip_data = NetPacket::IP::strip($raw_pkt);
342
343=head1 DESCRIPTION
344
345C<NetPacket::IP> provides a set of routines for assembling and
346disassembling packets using IP (Internet Protocol).
347
348=head2 Methods
349
350=over
351
352=item C<NetPacket::IP-E<gt>decode([RAW PACKET])>
353
354Decode the raw packet data given and return an object containing
355instance data.  This method will quite happily decode garbage input.
356It is the responsibility of the programmer to ensure valid packet data
357is passed to this method.
358
359=item C<NetPacket::IP-E<gt>encode()>
360
361Return an IP packet encoded with the instance data specified. This
362will infer the total length of the packet automatically from the
363payload length and also adjust the checksum.
364
365=back
366
367=head2 Functions
368
369=over
370
371=item C<NetPacket::IP::strip([RAW PACKET])>
372
373Return the encapsulated data (or payload) contained in the IP
374packet.  This data is suitable to be used as input for other
375C<NetPacket::*> modules.
376
377This function is equivalent to creating an object using the
378C<decode()> constructor and returning the C<data> field of that
379object.
380
381=back
382
383=head2 Instance data
384
385The instance data for the C<NetPacket::IP> object consists of
386the following fields.
387
388=over
389
390=item ver
391
392The IP version number of this packet.
393
394=item hlen
395
396The IP header length of this packet.
397
398=item flags
399
400The IP header flags for this packet.
401
402=item foffset
403
404The IP fragment offset for this packet.
405
406=item tos
407
408The type-of-service for this IP packet.
409
410=item len
411
412The length (including length of header) in bytes for this packet.
413
414=item id
415
416The identification (sequence) number for this IP packet.
417
418=item ttl
419
420The time-to-live value for this packet.
421
422=item proto
423
424The IP protocol number for this packet.
425
426=item cksum
427
428The IP checksum value for this packet.
429
430=item src_ip
431
432The source IP address for this packet in dotted-quad notation.
433
434=item dest_ip
435
436The destination IP address for this packet in dotted-quad notation.
437
438=item options
439
440Any IP options for this packet.
441
442=item data
443
444The encapsulated data (payload) for this IP packet.
445
446=back
447
448=head2 Exports
449
450=over
451
452=item default
453
454none
455
456=item exportable
457
458IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP IP_PROTO_IPIP IP_PROTO_TCP
459IP_PROTO_UDP IP_VERSION_IPv4
460
461=item tags
462
463The following tags group together related exportable items.
464
465=over
466
467=item C<:protos>
468
469IP_PROTO_IP IP_PROTO_ICMP IP_PROTO_IGMP IP_PROTO_IPIP
470IP_PROTO_TCP IP_PROTO_UDP
471
472=item C<:versions>
473
474IP_VERSION_IPv4
475
476=item C<:strip>
477
478Import the strip function C<ip_strip>.
479
480=item C<:ALL>
481
482All the above exportable items.
483
484=back
485
486=back
487
488=head1 EXAMPLE
489
490The following script dumps IP frames by IP address and protocol
491to standard output.
492
493  #!/usr/bin/perl -w
494
495  use strict;
496  use Net::PcapUtils;
497  use NetPacket::Ethernet qw(:strip);
498  use NetPacket::IP;
499
500  sub process_pkt {
501      my ($user, $hdr, $pkt) = @_;
502
503      my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
504      print("$ip_obj->{src_ip}:$ip_obj->{dest_ip} $ip_obj->{proto}\n");
505  }
506
507  Net::PcapUtils::loop(\&process_pkt, FILTER => 'ip');
508
509=head1 TODO
510
511=over
512
513=item IP option decoding - currently stored in binary form.
514
515=item Assembly of received fragments
516
517=back
518
519=head1 COPYRIGHT
520
521Copyright (c) 2001 Tim Potter and Stephanie Wehner.
522
523Copyright (c) 1995,1996,1997,1998,1999 ANU and CSIRO on behalf of
524the participants in the CRC for Advanced Computational Systems
525('ACSys').
526
527This module is free software.  You can redistribute it and/or
528modify it under the terms of the Artistic License 2.0.
529
530This program is distributed in the hope that it will be useful,
531but without any warranty; without even the implied warranty of
532merchantability or fitness for a particular purpose.
533
534=head1 AUTHOR
535
536Tim Potter E<lt>tpot@samba.orgE<gt>
537
538Stephanie Wehner E<lt>atrak@itsx.comE<gt>
539
540=cut
541
542__END__
543
544
545# any real autoloaded methods go after this line
546