File Coverage

blib/lib/NetPacket/UDP.pm
Criterion Covered Total %
statement 37 37 100.0
branch 3 4 75.0
condition n/a
subroutine 10 10 100.0
pod 2 4 50.0
total 52 55 94.5


line stmt bran cond sub pod time code
1             package NetPacket::UDP;
2             BEGIN {
3 4     4   24191 $NetPacket::UDP::AUTHORITY = 'cpan:YANICK';
4             }
5             # ABSTRACT: Assemble and disassemble UDP (User Datagram Protocol) packets.
6             $NetPacket::UDP::VERSION = '1.6.0';
7 4     4   25 use strict;
  4         6  
  4         127  
8 4     4   16 use warnings;
  4         6  
  4         130  
9              
10 4     4   912 use parent 'NetPacket';
  4         272  
  4         28  
11 4     4   970 use NetPacket::IP;
  4         7  
  4         1240  
12              
13             our @EXPORT_OK = qw(udp_strip);
14              
15             our %EXPORT_TAGS = (
16             ALL => [@EXPORT_OK],
17             strip => [qw(udp_strip)],
18             );
19              
20             #
21             # Decode the packet
22             #
23              
24             sub decode {
25 3     3 1 25 my $class = shift;
26 3         4 my($pkt, $parent) = @_;
27 3         8 my $self = {};
28              
29             # Class fields
30              
31 3         6 $self->{_parent} = $parent;
32 3         5 $self->{_frame} = $pkt;
33              
34             # Decode UDP packet
35              
36 3 50       7 if (defined($pkt)) {
37              
38 3         19 ($self->{src_port}, $self->{dest_port}, $self->{len}, $self->{cksum},
39             $self->{data}) = unpack("nnnna*", $pkt);
40             }
41              
42             # Return a blessed object
43              
44 3         6 bless($self, $class);
45 3         11 return $self;
46             }
47              
48             #
49             # Strip header from packet and return the data contained in it
50             #
51              
52             undef &udp_strip;
53             *udp_strip = \&strip;
54              
55             sub strip {
56 1     1 1 2 return decode(__PACKAGE__,shift)->{data};
57             }
58              
59             #
60             # Encode a packet
61             #
62              
63             sub encode {
64 1     1 0 1919 my ($self, $ip) = @_;
65            
66             # Adjust the length accordingly
67 1         4 $self->{len} = 8 + length($self->{data});
68              
69             # First of all, fix the checksum
70 1         3 $self->checksum($ip);
71              
72             # Put the packet together
73 1         7 return pack("nnnna*", $self->{src_port},$self->{dest_port},
74             $self->{len}, $self->{cksum}, $self->{data});
75              
76             }
77              
78             #
79             # UDP Checksum
80             #
81              
82             sub checksum {
83              
84 3     3 0 1039 my( $self, $ip ) = @_;
85              
86 3         7 my $proto = NetPacket::IP::IP_PROTO_UDP;
87              
88             # Pack pseudo-header for udp checksum
89              
90 3         325 my $src_ip = gethostbyname($ip->{src_ip});
91 3         91 my $dest_ip = gethostbyname($ip->{dest_ip});
92              
93 4     4   26 no warnings;
  4         5  
  4         531  
94              
95 3         36 my $packet = pack 'a4a4CCnnnnna*' =>
96              
97             # fake ip header part
98             $src_ip, $dest_ip, 0, $proto, $self->{len},
99              
100             # proper UDP part
101             $self->{src_port}, $self->{dest_port}, $self->{len}, 0, $self->{data};
102              
103 3 100       19 $packet .= "\x00" if length($packet) % 2;
104              
105 3         13 $self->{cksum} = NetPacket::htons(NetPacket::in_cksum($packet));
106              
107             }
108              
109             1;
110              
111             __END__