File Coverage

blib/lib/Metabrik/Client/Tcpdump.pm
Criterion Covered Total %
statement 9 63 14.2
branch 0 28 0.0
condition 0 31 0.0
subroutine 3 9 33.3
pod 2 5 40.0
total 14 136 10.2


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # client::tcpdump Brik
5             #
6             package Metabrik::Client::Tcpdump;
7 1     1   689 use strict;
  1         3  
  1         30  
8 1     1   5 use warnings;
  1         2  
  1         27  
9              
10 1     1   5 use base qw(Metabrik::Network::Read);
  1         2  
  1         508  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             datadir => [ qw(datadir) ],
20             output => [ qw(output) ],
21             device => [ qw(device) ], # Inherited
22             layer => [ qw(2|3|4) ], # Inherited
23             filter => [ qw(pcap_filter) ], # Inherited
24             count => [ qw(count) ], # Inherited
25             _sp => [ qw(INTERNAL) ],
26             _pidfile => [ qw(INTERNAL) ],
27             },
28             commands => {
29             capture => [ qw(output layer|OPTIONAL device|OPTIONAL filter|OPTIONAL count|OPTIONAL) ],
30             capture_in_background => [ qw(output layer|OPTIONAL device|OPTIONAL filter|OPTIONAL count|OPTIONAL) ],
31             stop => [ ],
32             },
33             require_modules => {
34             'Metabrik::File::Pcap' => [ ],
35             'Metabrik::System::File' => [ ],
36             'Metabrik::System::Process' => [ ],
37             },
38             };
39             }
40              
41             sub brik_use_properties {
42 0     0 1   my $self = shift;
43              
44             return {
45 0   0       attributes_default => {
46             device => defined($self->global) && $self->global->device || 'eth0',
47             },
48             };
49             }
50              
51             sub capture {
52 0     0 0   my $self = shift;
53 0           my ($output, $layer, $device, $filter, $count) = @_;
54              
55 0   0       $layer ||= $self->layer;
56 0   0       $device ||= $self->device;
57 0   0       $filter ||= $self->filter;
58 0   0       $count ||= $self->count;
59 0 0         $self->brik_help_run_undef_arg('capture', $output) or return;
60              
61 0 0         my $fp = Metabrik::File::Pcap->new_from_brik_init($self) or return;
62 0 0         $fp->open($output, 'write') or return;
63              
64 0 0         $self->open($layer, $device, $filter) or return;
65              
66 0           my $read_count = 0;
67 0           while (1) {
68 0 0 0       if (my $next = $self->read or next) {
69 0 0         if (@$next > 0) {
70 0           $read_count += @$next;
71 0           $fp->write($next);
72             }
73             }
74 0           $self->log->debug("capture: read returned");
75              
76             # We need to reset the timeout, otherwise read() will
77             # always return immediately after each call, causing a full CPU
78             # to become busy. Yes, read() is blocking until a timeout occurs.
79 0 0         if ($self->has_timeout) {
80 0           $self->reset_timeout;
81             }
82              
83 0 0 0       last if $count && $read_count >= $count;
84             }
85              
86 0           $self->close;
87              
88 0           $fp->close;
89              
90 0           return $read_count;
91             }
92              
93             sub capture_in_background {
94 0     0 0   my $self = shift;
95 0           my ($output, $layer, $device, $filter, $count) = @_;
96              
97 0   0       $layer ||= $self->layer;
98 0   0       $device ||= $self->device;
99 0   0       $filter ||= $self->filter;
100 0   0       $count ||= $self->count;
101 0 0         $self->brik_help_run_undef_arg('capture_in_background', $output) or return;
102              
103 0 0         my $sf = Metabrik::System::File->new_from_brik_init($self) or return;
104              
105 0           my $datadir = $self->datadir;
106 0 0         if ($sf->is_relative($output)) {
107 0 0         my $basefile = $sf->basefile($output) or return;
108 0           $output = $datadir.'/'.$basefile;
109             }
110              
111 0           $self->log->info("capture_in_background: writing to output [$output]");
112              
113 0 0         my $sp = Metabrik::System::Process->new_from_brik_init($self) or return;
114 0           $sp->close_output_on_start(0);
115              
116             my $pidfile = $sp->start_with_pidfile(sub {
117 0     0     $self->capture($output, $layer, $device, $filter, $count)
118 0           });
119              
120 0           $self->_sp($sp);
121 0           $self->_pidfile($pidfile);
122              
123 0           return $pidfile;
124             }
125              
126             sub stop {
127 0     0 0   my $self = shift;
128              
129 0           my $sp = $self->_sp;
130 0           my $pidfile = $self->_pidfile;
131              
132 0 0         if (defined($sp)) {
133 0           $sp->kill_from_pidfile($pidfile);
134 0           $self->_sp(undef);
135 0           $self->_pidfile(undef);
136             }
137              
138 0           return 1;
139             }
140              
141             1;
142              
143             __END__