File Coverage

blib/lib/NetPacket/Ethernet.pm
Criterion Covered Total %
statement 73 82 89.0
branch 2 4 50.0
condition n/a
subroutine 20 22 90.9
pod 3 4 75.0
total 98 112 87.5


line stmt bran cond sub pod time code
1             package NetPacket::Ethernet;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: Assemble and disassemble ethernet packets.
4             $NetPacket::Ethernet::VERSION = '1.7.2';
5 9     9   352474 use strict;
  9         65  
  9         302  
6 9     9   49 use warnings;
  9         20  
  9         287  
7              
8 9     9   2367 use parent 'NetPacket';
  9         1597  
  9         55  
9              
10             my @eth_types = qw/ ETH_TYPE_IP
11             ETH_TYPE_ARP
12             ETH_TYPE_APPLETALK
13             ETH_TYPE_RARP
14             ETH_TYPE_SNMP
15             ETH_TYPE_IPv6
16             ETH_TYPE_PPP
17             ETH_TYPE_802_1Q
18             ETH_TYPE_IPX
19             ETH_TYPE_PPPOED
20             ETH_TYPE_PPPOES /;
21              
22             our @EXPORT_OK = ( 'eth_strip', 'ETH_HLEN', @eth_types );
23              
24             our %EXPORT_TAGS = (
25             ALL => [@EXPORT_OK],
26             strip => [qw(eth_strip)],
27             types => \@eth_types,
28             );
29              
30             #
31             # Partial list of ethernet protocol types from
32             # http://www.isi.edu/in-notes/iana/assignments/ethernet-numbers
33             #
34              
35 9     9   1083 use constant ETH_TYPE_IP => 0x0800;
  9         20  
  9         778  
36 9     9   62 use constant ETH_TYPE_ARP => 0x0806;
  9         18  
  9         479  
37 9     9   63 use constant ETH_TYPE_APPLETALK => 0x809b;
  9         39  
  9         491  
38 9     9   58 use constant ETH_TYPE_RARP => 0x8035;
  9         18  
  9         459  
39 9     9   57 use constant ETH_TYPE_SNMP => 0x814c;
  9         23  
  9         470  
40 9     9   53 use constant ETH_TYPE_IPv6 => 0x86dd;
  9         17  
  9         489  
41 9     9   55 use constant ETH_TYPE_PPP => 0x880b;
  9         16  
  9         497  
42 9     9   58 use constant ETH_TYPE_802_1Q => 0x8100;
  9         31  
  9         533  
43 9     9   59 use constant ETH_TYPE_IPX => 0x8137;
  9         18  
  9         470  
44 9     9   56 use constant ETH_TYPE_PPPOED => 0x8863;
  9         15  
  9         484  
45 9     9   64 use constant ETH_TYPE_PPPOES => 0x8864;
  9         30  
  9         456  
46              
47 9     9   54 use constant ETH_HLEN => 6;
  9         16  
  9         486  
48              
49             #
50             # VLAN Tag field masks
51             #
52              
53 9     9   55 use constant VLAN_MASK_PCP => 0xE000;
  9         15  
  9         456  
54 9     9   53 use constant VLAN_MASK_CFI => 0x1000;
  9         15  
  9         440  
55 9     9   160 use constant VLAN_MASK_VID => 0x0FFF;
  9         24  
  9         4679  
56              
57             #
58             # Decode the packet
59             #
60              
61             sub decode {
62 19     19 1 56332 my $class = shift;
63 19         66 my($pkt, $parent) = @_;
64 19         55 my $self = {};
65              
66             # Class fields
67              
68 19         67 $self->{_parent} = $parent;
69 19         49 $self->{_frame} = $pkt;
70              
71             # Decode ethernet packet
72              
73 19 50       84 if (defined($pkt)) {
74              
75 19         45 my($sm_lo, $sm_hi, $dm_lo, $dm_hi, $tcid);
76              
77 19         137 ($dm_hi, $dm_lo, $sm_hi, $sm_lo, $self->{type}) = unpack('NnNnn' ,
78             $pkt);
79              
80             # Check for 802.1Q VLAN tag and unpack to account for 4-byte offset
81 19 50       78 if ($self->{type} == ETH_TYPE_802_1Q) {
82 0         0 $self->{tpid} = ETH_TYPE_802_1Q;
83              
84 0         0 ( $tcid, $self->{type}, $self->{data} ) = unpack('x14nna*' , $pkt);
85              
86             # Break down VLAN tag TCI into: PCP, CFI, VID
87 0         0 $self->{pcp} = $tcid & VLAN_MASK_PCP >> 13;
88 0         0 $self->{cfi} = $tcid & VLAN_MASK_CFI >> 12;
89 0         0 $self->{vid} = $tcid & VLAN_MASK_VID;
90             }
91             else {
92 19         96 ( $self->{data} ) = unpack('x14a*' , $pkt);
93             }
94              
95             # Convert MAC addresses to hex string to avoid representation problems
96              
97 19         116 $self->{src_mac} = sprintf "%08x%04x", $sm_hi, $sm_lo;
98 19         78 $self->{dest_mac} = sprintf "%08x%04x", $dm_hi, $dm_lo;
99             }
100              
101             # Return a blessed object
102              
103 19         45 bless($self, $class);
104 19         70 return $self;
105             }
106              
107             #
108             # Strip header from packet and return the data contained in it
109             #
110              
111             sub eth_strip {
112 0     0 0 0 goto \&strip;
113             }
114              
115             sub strip {
116 0     0 1 0 my ($pkt) = @_;
117              
118 0         0 my $eth_obj = NetPacket::Ethernet->decode($pkt);
119 0         0 return $eth_obj->{data};
120             }
121              
122             sub encode {
123 1     1 1 2306 my ($self) = shift;
124              
125 1         3 my @mac = map { $self->{$_} } qw/ dest_mac src_mac /;
  2         6  
126 1         6 s/://g for @mac;
127              
128 1         15 return pack 'H12H12n a*', @mac, 0x0800, $self->{data};
129             }
130              
131             1;
132              
133             =pod
134              
135             =head1 NAME
136              
137             NetPacket::Ethernet - Assemble and disassemble ethernet packets.
138              
139             =head1 VERSION
140              
141             version 1.7.2
142              
143             =head1 SYNOPSIS
144              
145             use NetPacket::Ethernet;
146              
147             $eth_obj = NetPacket::Ethernet->decode($raw_pkt);
148             $eth_pkt = NetPacket::Ethernet->encode(params...); # Not implemented
149             $eth_data = NetPacket::Ethernet::strip($raw_pkt);
150              
151             =head1 DESCRIPTION
152              
153             C provides a set of routines for assembling and
154             disassembling packets using the Ethernet protocol.
155              
156             =head2 Methods
157              
158             =over
159              
160             =item Cdecode([RAW PACKET])>
161              
162             Decode the raw packet data given and return an object containing
163             instance data. This method will quite happily decode garbage input.
164             It is the responsibility of the programmer to ensure valid packet data
165             is passed to this method.
166              
167             =item Cencode(param =E value)>
168              
169             Return an ethernet packet encoded with the instance data specified.
170             Not implemented.
171              
172             =back
173              
174             =head2 Functions
175              
176             =over
177              
178             =item C
179              
180             Return the encapsulated data (or payload) contained in the ethernet
181             packet. This data is suitable to be used as input for other
182             C modules.
183              
184             This function is equivalent to creating an object using the
185             C constructor and returning the C field of that
186             object.
187              
188             =back
189              
190             =head2 Instance data
191              
192             The instance data for the C object consists of
193             the following fields.
194              
195             =over
196              
197             =item src_mac
198              
199             The source MAC address for the ethernet packet as a hex string.
200              
201             =item dest_mac
202              
203             The destination MAC address for the ethernet packet as a hex string.
204              
205             =item type
206              
207             The protocol type for the ethernet packet.
208              
209             =item data
210              
211             The payload for the ethernet packet.
212              
213             =back
214              
215             =head2 Exports
216              
217             =over
218              
219             =item default
220              
221             none
222              
223             =item exportable
224              
225             ETH_TYPE_IP ETH_TYPE_ARP ETH_TYPE_APPLETALK ETH_TYPE_SNMP
226             ETH_TYPE_IPv6 ETH_TYPE_PPP
227              
228             =item tags
229              
230             The following tags group together related exportable items.
231              
232             =over
233              
234             =item C<:types>
235              
236             ETH_TYPE_IP ETH_TYPE_ARP ETH_TYPE_APPLETALK ETH_TYPE_SNMP
237             ETH_TYPE_IPv6 ETH_TYPE_PPP
238              
239             =item C<:strip>
240              
241             Import the strip function C which is an alias for
242             C
243              
244             =item C<:ALL>
245              
246             All the above exportable items.
247              
248             =back
249              
250             =back
251              
252             =head1 EXAMPLE
253              
254             The following script dumps ethernet frames by mac address and protocol
255             to standard output.
256              
257             #!/usr/bin/perl -w
258              
259             use strict;
260             use Net::PcapUtils;
261             use NetPacket::Ethernet;
262              
263             sub process_pkt {
264             my($arg, $hdr, $pkt) = @_;
265              
266             my $eth_obj = NetPacket::Ethernet->decode($pkt);
267             print("$eth_obj->{src_mac}:$eth_obj->{dest_mac} $eth_obj->{type}\n");
268             }
269              
270             Net::PcapUtils::loop(\&process_pkt);
271              
272             =head1 TODO
273              
274             =over
275              
276             =item Implement C function
277              
278             =back
279              
280             =head1 COPYRIGHT
281              
282             Copyright (c) 2001 Tim Potter and Stephanie Wehner.
283              
284             Copyright (c) 1995,1996,1997,1998,1999 ANU and CSIRO on behalf of
285             the participants in the CRC for Advanced Computational Systems
286             ('ACSys').
287              
288             This module is free software. You can redistribute it and/or
289             modify it under the terms of the Artistic License 2.0.
290              
291             This program is distributed in the hope that it will be useful,
292             but without any warranty; without even the implied warranty of
293             merchantability or fitness for a particular purpose.
294              
295             =head1 AUTHOR
296              
297             Tim Potter Etpot@samba.orgE
298              
299             =cut
300              
301             __END__