File Coverage

blib/lib/Parse/Netstat/Search/Sort.pm
Criterion Covered Total %
statement 56 78 71.7
branch 29 56 51.7
condition 2 6 33.3
subroutine 10 10 100.0
pod 5 5 100.0
total 102 155 65.8


line stmt bran cond sub pod time code
1             package Parse::Netstat::Search::Sort;
2              
3 2     2   143219 use 5.006;
  2         21  
4 2     2   11 use strict;
  2         4  
  2         45  
5 2     2   28 use warnings;
  2         6  
  2         81  
6 2     2   12 use base 'Error::Helper';
  2         4  
  2         709  
7 2     2   2140 use Net::IP;
  2         119373  
  2         2136  
8              
9             =head1 NAME
10              
11             Parse::Netstat::Search::Sort - Sorts the returned array from Parse::Netstat::Search.
12              
13             =head1 VERSION
14              
15             Version 0.0.0
16              
17             =cut
18              
19             our $VERSION = '0.0.0';
20              
21              
22             =head1 SYNOPSIS
23              
24             use Parse::Netstat::Search;
25             use Parse::Netstat::Search::Sort;
26             use Parse::Netstat qw(parse_netstat);
27              
28             my $res = parse_netstat(output => join("", `netstat -n`), tcp=>1, udp=>1, unix=>0, flavor=>$^O);
29              
30             my $pn-search=Parse::Netstat::Search->new;
31              
32             my @found=$pn-search->search( $res );
33              
34             my $sorter = Parse::Netstat::Search::Sort->new;
35              
36             @found = $sorter->sort( \@found );
37              
38             The supported sort methods are as below.
39              
40             host_f Host, Foreign (default)
41             host_l Host, Local
42             port_f Port, Foriegn
43             port_l Port, Local
44             state State
45             protocol Protocol
46             q_r Queue, Receive
47             q_s Queue, Send
48             none No sorting is done.
49              
50             These dual sort can take noticably longer than the ones above.
51              
52             host_ff Host, Foreign First
53             host_lf Host, Local First
54             port_ff Port, Foreign First
55             port_lf Port, Local First
56             q_rf Queue, Receive First
57             q_sf Queue, Send First
58              
59             =head1 Methods
60              
61             =head2 new
62              
63             Initiates the object.
64              
65             my $sorter=Parse::Netstat::Search->new;
66              
67             =cut
68              
69             sub new{
70 1     1 1 141 my $self={
71             perror=>undef,
72             error=>undef,
73             errorString=>'',
74             errorExtra=>{
75             1 => 'badSort',
76             2 => 'badArray',
77             },
78             sort=>'host_f',
79             invert=>undef,
80             sort_check=>{
81             host_ff=>1,
82             host_lf=>1,
83             host_f=>1,
84             host_l=>1,
85             port_ff=>1,
86             port_lf=>1,
87             port_f=>1,
88             port_l=>1,
89             state=>1,
90             protocol=>1,
91             q_rf=>1,
92             q_sf=>1,
93             q_r=>1,
94             q_s=>1,
95             none=>1,
96             }
97             };
98 1         3 bless $self;
99              
100 1         3 return $self;
101             }
102              
103             =head2 get_sort
104              
105             This returns the current sort method.
106              
107             my $sort=$pnc->get_sort;
108              
109             =cut
110              
111             sub get_sort{
112 1     1 1 6 my $self=$_[0];
113              
114 1 50       3 if( ! $self->errorblank ){
115 0         0 return undef;
116             }
117              
118 1         11 return $self->{sort};
119             }
120              
121             =head2 set_sort
122              
123             This sets the sort method to be used and if it should
124             be inverted.
125              
126             The first argument is the sort method name and the second is a
127             boolean on if it should be inverted or not.
128              
129             Leaving either undef resets the undef value back to the default.
130              
131             The supported sorting methods are as below.
132              
133             $ sorter->set_sort( $sort_method );
134             if( $sorter->error ){
135             warn( '"'.$sort_method.'"' is not a valid sort method );
136             }
137            
138             # reset to defaults
139             $sorter->set_sort
140            
141             # Set the sort method to host_f and invert.
142             $sorter->set_sort( 'host_f' )
143              
144             =cut
145              
146             sub set_sort{
147 7     7 1 4432 my $self=$_[0];
148 7         60 my $sort=$_[1];
149              
150 7 50       29 if( ! $self->errorblank ){
151 0         0 return undef;
152             }
153              
154 7 50       80 if (!defined( $sort ) ){
155 0         0 $sort='host_f';
156             }
157              
158 7         17 $self->{sort}=$sort;
159              
160 7         15 return 1;
161             }
162              
163             =head2 sort
164              
165             Sorts the provided array from Parse::Netstat::Search.
166              
167             my @sorted=$sorter->sort( \@found );
168              
169             =cut
170              
171             sub sort{
172 8     8 1 327 my $self=$_[0];
173 8         12 my @found;
174 8 50 33     76 if (
175             defined( $_[1] ) &&
176             ( ref($_[1]) eq 'ARRAY' )
177             ){
178 8         13 @found=@{ $_[1] };
  8         24  
179             }else{
180 0         0 $self->{error}=2;
181 0         0 $self->{errorString}='The passed item is either not a array or undefined';
182 0         0 $self->warn;
183 0         0 return undef;
184             }
185              
186 8 50       26 if( ! $self->errorblank ){
187 0         0 return undef;
188             }
189              
190             # handle sorting if needed
191 8 50       87 if ( $self->{sort} ne 'none' ){
192 8 50       79 if( $self->{sort} eq 'host_ff' ){
    50          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    50          
    100          
    50          
193             @found=sort {
194 0         0 &host_sort_helper( $a->{foreign_host} ) <=> &host_sort_helper( $b->{foreign_host} ) or
195             &host_sort_helper( $a->{local_host} ) <=> &host_sort_helper( $b->{local_host} )
196 0 0       0 } @found;
197             }elsif( $self->{sort} eq 'host_lf' ){
198             @found=sort {
199 0         0 &host_sort_helper( $a->{local_host} ) <=> &host_sort_helper( $b->{local_host} ) or
200             &host_sort_helper( $a->{foreign_host} ) <=> &host_sort_helper( $b->{foreign_host} )
201 0 0       0 } @found;
202             }elsif( $self->{sort} eq 'host_f' ){
203             @found=sort {
204 1         5 &host_sort_helper( $a->{foreign_host} ) <=> &host_sort_helper( $b->{foreign_host} )
205 5         150 } @found;
206             }elsif( $self->{sort} eq 'host_l' ){
207             @found=sort {
208 1         8 &host_sort_helper( $a->{local_host} ) <=> &host_sort_helper( $b->{local_host} )
209 5         116 } @found;
210             }elsif( $self->{sort} eq 'port_ff' ){
211             @found=sort {
212 0         0 $a->{foreign_port} <=> $b->{foreign_port} or
213             $a->{local_port} <=> $b->{local_port}
214 0 0       0 } @found;
215             }elsif( $self->{sort} eq 'port_lf' ){
216             @found=sort {
217 0         0 $a->{local_port} <=> $b->{local_port} or
218             $a->{foreign_port} <=> $b->{foreign_port}
219 0 0       0 } @found;
220             }elsif( $self->{sort} eq 'port_f' ){
221             @found=sort {
222 1         5 $a->{foreign_port} <=> $b->{foreign_port}
223 5         12 } @found;
224             }elsif( $self->{sort} eq 'port_l' ){
225             @found=sort {
226 1         6 $a->{local_port} <=> $b->{local_port}
227 5         14 } @found;
228             }elsif( $self->{sort} eq 'state' ){
229             @found=sort {
230 1         6 $a->{state} cmp $b->{state}
231 5         12 } @found;
232             }elsif( $self->{sort} eq 'protocol' ){
233             @found=sort {
234 1         5 $a->{proto} cmp $b->{proto}
235 4         11 } @found;
236             }elsif( $self->{sort} eq 'q_rf' ){
237             @found=sort {
238 0         0 $a->{recvq} <=> $b->{recvq} or
239             $a->{sendq} <=> $b->{sendq}
240 0 0       0 } @found;
241             }elsif( $self->{sort} eq 'q_sf' ){
242             @found=sort {
243 0         0 $a->{sendq} <=> $b->{sendq} or
244             $a->{recvq} <=> $b->{recvq}
245 0 0       0 } @found;
246             }elsif( $self->{sort} eq 'q_r' ){
247             @found=sort {
248 1         5 $a->{recvq} <=> $b->{recvq}
249 4         11 } @found;
250             }elsif( $self->{sort} eq 'q_s' ){
251             @found=sort {
252 1         5 $a->{sendq} <=> $b->{sendq}
253 5         14 } @found;
254             }
255             }
256              
257 8         92 return @found;
258             }
259              
260             =head2 host_sort_helper
261              
262             Internal function.
263              
264             Takes a host and converts it to a number.
265              
266             =cut
267              
268             sub host_sort_helper{
269 20 50 33 20 1 93 if (
270             ( !defined($_[0]) ) ||
271             ( $_[0] eq '*' )
272             ){
273 0         0 return 0;
274             }
275 20         37 my $host=eval { Net::IP->new( $_[0] )->intip} ;
  20         67  
276 20 50       100413 if (!defined( $host )){
277 0         0 return 0;
278             }
279 20         91 return $host;
280             }
281              
282             =head1 ERROR CODES / FLAGS
283              
284             Error handling is provided by L.
285              
286             =head2 1 / badSort
287              
288             Invalid value specified for sort.
289              
290             =head2 2 / badArray
291              
292             The passed item is not a array.
293              
294             =head1 AUTHOR
295              
296             Zame C. Bowers-Hadley, C<< >>
297              
298             =head1 BUGS
299              
300             Please report any bugs or feature requests to C, or through
301             the web interface at L. I will be notified, and then you'll
302             automatically be notified of progress on your bug as I make changes.
303              
304              
305              
306              
307             =head1 SUPPORT
308              
309             You can find documentation for this module with the perldoc command.
310              
311             perldoc Parse::Netstat::Search::Sort
312              
313              
314             You can also look for information at:
315              
316             =over 4
317              
318             =item * RT: CPAN's request tracker (report bugs here)
319              
320             L
321              
322             =item * AnnoCPAN: Annotated CPAN documentation
323              
324             L
325              
326             =item * CPAN Ratings
327              
328             L
329              
330             =item * Search CPAN
331              
332             L
333              
334             =item * Code Rep
335              
336             L
337              
338             =back
339              
340              
341             =head1 ACKNOWLEDGEMENTS
342              
343              
344             =head1 LICENSE AND COPYRIGHT
345              
346             Copyright 2019 Zame C. Bowers-Hadley.
347              
348             This program is free software; you can redistribute it and/or modify it
349             under the terms of the the Artistic License (2.0). You may obtain a
350             copy of the full license at:
351              
352             L
353              
354             Any use, modification, and distribution of the Standard or Modified
355             Versions is governed by this Artistic License. By using, modifying or
356             distributing the Package, you accept this license. Do not use, modify,
357             or distribute the Package, if you do not accept this license.
358              
359             If your Modified Version has been derived from a Modified Version made
360             by someone other than you, you are nevertheless required to ensure that
361             your Modified Version complies with the requirements of this license.
362              
363             This license does not grant you the right to use any trademark, service
364             mark, tradename, or logo of the Copyright Holder.
365              
366             This license includes the non-exclusive, worldwide, free-of-charge
367             patent license to make, have made, use, offer to sell, sell, import and
368             otherwise transfer the Package with respect to any patent claims
369             licensable by the Copyright Holder that are necessarily infringed by the
370             Package. If you institute patent litigation (including a cross-claim or
371             counterclaim) against any party alleging that the Package constitutes
372             direct or contributory patent infringement, then this Artistic License
373             to you shall terminate on the date that such litigation is filed.
374              
375             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
376             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
377             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
378             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
379             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
380             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
381             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
382             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
383              
384              
385             =cut
386              
387             1; # End of Parse::Netstat::Search::Sort