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