File Coverage

blib/lib/Net/Frame/Dump.pm
Criterion Covered Total %
statement 34 36 94.4
branch n/a
condition n/a
subroutine 12 12 100.0
pod n/a
total 46 48 95.8


line stmt bran cond sub pod time code
1             #
2             # $Id: Dump.pm 364 2014-11-30 11:26:27Z gomor $
3             #
4             package Net::Frame::Dump;
5 1     1   6189 use strict;
  1         2  
  1         44  
6 1     1   7 use warnings;
  1         2  
  1         173  
7              
8             our $VERSION = '1.14';
9              
10 1     1   7 use base qw(Class::Gomor::Array Exporter);
  1         11  
  1         728  
11              
12             our %EXPORT_TAGS = (
13             consts => [qw(
14             NF_DUMP_LAYER_NULL
15             NF_DUMP_LAYER_ETH
16             NF_DUMP_LAYER_RAW
17             NF_DUMP_LAYER_SLL
18             NF_DUMP_LAYER_PPP
19             NF_DUMP_LAYER_80211_RADIOTAP
20             NF_DUMP_LAYER_80211
21             NF_DUMP_LAYER_ERF
22             )],
23             );
24             our @EXPORT_OK = (
25             @{$EXPORT_TAGS{consts}},
26             );
27              
28 1     1   15119 use constant NF_DUMP_LAYER_NULL => 0;
  1         2  
  1         123  
29 1     1   7 use constant NF_DUMP_LAYER_ETH => 1;
  1         2  
  1         58  
30 1     1   11 use constant NF_DUMP_LAYER_PPP => 9;
  1         2  
  1         58  
31 1     1   6 use constant NF_DUMP_LAYER_RAW => 12;
  1         2  
  1         59  
32 1     1   6 use constant NF_DUMP_LAYER_80211 => 105;
  1         2  
  1         60  
33 1     1   6 use constant NF_DUMP_LAYER_SLL => 113;
  1         2  
  1         69  
34 1     1   6 use constant NF_DUMP_LAYER_80211_RADIOTAP => 127;
  1         1  
  1         66  
35 1     1   6 use constant NF_DUMP_LAYER_ERF => 175;
  1         2  
  1         128  
36              
37             our @AS = qw(
38             file
39             filter
40             overwrite
41             firstLayer
42             isRunning
43             keepTimestamp
44             _framesStored
45             _pcapd
46             _dumper
47             );
48             our @AA = qw(
49             frames
50             );
51             __PACKAGE__->cgBuildIndices;
52             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
53             __PACKAGE__->cgBuildAccessorsArray(\@AA);
54              
55 1     1   1297 use Net::Pcap;
  0            
  0            
56             use Time::HiRes qw(gettimeofday);
57             use Net::Frame::Layer qw(:consts :subs);
58              
59             sub new {
60             my $self = shift->SUPER::new(
61             filter => '',
62             overwrite => 0,
63             isRunning => 0,
64             keepTimestamp => 0,
65             frames => [],
66             _framesStored => {},
67             @_,
68             );
69              
70             if (!defined($self->file)) {
71             my $int = getRandom32bitsInt();
72             $self->file("netframe-tmp-$$.$int.pcap");
73             }
74              
75             return $self;
76             }
77              
78             sub flush {
79             my $self = shift;
80             $self->frames([]);
81             $self->_framesStored({});
82             }
83              
84             sub _addStore {
85             my $self = shift;
86             my ($oSimple) = @_;
87              
88             # If parameter, we store it
89             if ($oSimple) {
90             my $key = $oSimple->getKey;
91             push @{$self->_framesStored->{$key}}, $oSimple;
92              
93             # If it is ICMPv4, we store a second time
94             if (exists $oSimple->ref->{ICMPv4}) {
95             push @{$self->_framesStored->{$oSimple->ref->{ICMPv4}->getKey}},
96             $oSimple;
97             }
98             }
99              
100             # We return the hash ref
101             return $self->_framesStored;
102             }
103              
104             sub store {
105             my $self = shift;
106             my ($oSimple) = @_;
107              
108             $self->_addStore($oSimple);
109              
110             my @frames = $self->frames;
111             push @frames, $oSimple;
112             return $self->frames(\@frames);
113             }
114              
115             sub _getTimestamp {
116             my $self = shift;
117             my ($hdr) = @_;
118             $hdr->{tv_sec}.'.'.sprintf("%06d", $hdr->{tv_usec});
119             }
120              
121             sub _setTimestamp {
122             my $self = shift;
123             my @time = Time::HiRes::gettimeofday();
124             $time[0].'.'.sprintf("%06d", $time[1]);
125             }
126              
127             my $mapLinks = {
128             NF_DUMP_LAYER_NULL() => 'NULL',
129             NF_DUMP_LAYER_ETH() => 'ETH',
130             NF_DUMP_LAYER_RAW() => 'RAW',
131             NF_DUMP_LAYER_SLL() => 'SLL',
132             NF_DUMP_LAYER_PPP() => 'PPP',
133             NF_DUMP_LAYER_80211() => '80211',
134             NF_DUMP_LAYER_80211_RADIOTAP() => '80211::Radiotap',
135             NF_DUMP_LAYER_ERF() => 'ERF',
136             };
137              
138             sub getFirstLayer {
139             my $self = shift;
140             my $link = Net::Pcap::datalink($self->_pcapd);
141             $self->firstLayer($mapLinks->{$link} || NF_LAYER_UNKNOWN);
142             }
143              
144             sub next {
145             my $self = shift;
146              
147             my %hdr;
148             if (my $raw = Net::Pcap::next($self->_pcapd, \%hdr)) {
149             my $ts = $self->keepTimestamp ? $self->_getTimestamp(\%hdr)
150             : $self->_setTimestamp;
151             return {
152             firstLayer => $self->firstLayer,
153             timestamp => $ts,
154             raw => $raw,
155             };
156             }
157              
158             return;
159             }
160              
161             sub nextEx {
162             my $self = shift;
163              
164             my %hdr;
165             my $raw;
166             my $r = Net::Pcap::next_ex($self->_pcapd, \%hdr, \$raw);
167             if ($r > 0) {
168             my $ts = $self->keepTimestamp ? $self->_getTimestamp(\%hdr)
169             : $self->_setTimestamp;
170             return {
171             firstLayer => $self->firstLayer,
172             timestamp => $ts,
173             raw => $raw,
174             };
175             }
176              
177             return $r;
178             }
179              
180             sub getFramesFor {
181             my $self = shift;
182             my ($oSimple) = @_;
183              
184             my $results;
185             my $key = $oSimple->getKeyReverse;
186             push @$results, @{$self->_framesStored->{$key}}
187             if exists $self->_framesStored->{$key};
188              
189             # Add also ICMPv4
190             if (exists $self->_framesStored->{ICMPv4}) {
191             push @$results, @{$self->_framesStored->{ICMPv4}};
192             }
193              
194             return $results ? @$results : ();
195             }
196              
197             1;
198              
199             __END__