File Coverage

blib/lib/NetPacket/Ethernet.pm
Criterion Covered Total %
statement 69 82 84.1
branch 2 4 50.0
condition n/a
subroutine 20 22 90.9
pod 3 3 100.0
total 94 111 84.6


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