File Coverage

blib/lib/Net/Connection/Match/Ports.pm
Criterion Covered Total %
statement 49 70 70.0
branch 17 42 40.4
condition 12 30 40.0
subroutine 5 5 100.0
pod 2 2 100.0
total 85 149 57.0


line stmt bran cond sub pod time code
1             package Net::Connection::Match::Ports;
2              
3 3     3   262605 use 5.006;
  3         67  
4 3     3   18 use strict;
  3         6  
  3         79  
5 3     3   18 use warnings;
  3         14  
  3         2768  
6              
7             =head1 NAME
8              
9             Net::Connection::Match::Ports - Runs a basic port check against a Net::Connection object.
10              
11             =head1 VERSION
12              
13             Version 0.1.0
14              
15             =cut
16              
17             our $VERSION = '0.1.0';
18              
19              
20             =head1 SYNOPSIS
21              
22             use Net::Connection::Match::Port;
23             use Net::Connection;
24            
25             my $connection_args={
26             foreign_host=>'10.0.0.1',
27             foreign_port=>'22',
28             local_host=>'10.0.0.2',
29             local_port=>'12322',
30             proto=>'tcp4',
31             state=>'ESTABLISHED',
32             };
33            
34             my $conn=Net::Connection->new( $connection_args );
35            
36             my %args=(
37             ports=>[
38             'smtp',
39             '22',
40             ],
41             lports=>[
42             '21',
43             ],
44             fports=>[
45             'http',
46             '*',
47             ],
48             );
49            
50             my $checker=Net::Connection::Match::Ports->new( \%args );
51            
52             if ( $checker->match( $conn ) ){
53             print "It matches.\n";
54             }
55              
56             =head1 METHODS
57              
58             =head2 new
59              
60             This intiates the object.
61              
62             It takes a hash reference with atleast one of of the three
63             possible keys defined. The possible keys are 'ports'(which
64             matches either side), 'lports'(which matches the local side),
65             and 'fports'(which matches the foreign side).
66              
67             The value of each key is a array with either port numbers, '*', or
68             names. If names are given, getservbyname will be called. If
69             it errors for any of them, it will die.
70              
71             If the new method fails, it dies.
72              
73             my %args=(
74             ports=>[
75             'smtp',
76             '22',
77             ],
78             lports=>[
79             '21',
80             ],
81             fports=>[
82             'http',
83             ],
84             );
85            
86             my $checker=Net::Connection::Match::Ports->new( \%args );
87              
88             =cut
89              
90             sub new{
91 4     4 1 1100 my %args;
92 4 100       14 if(defined($_[1])){
93 3         8 %args= %{$_[1]};
  3         17  
94             };
95              
96             # run some basic checks to make sure we have the minimum stuff required to work
97 4 50 66     22 if (
      33        
98             ( ! defined( $args{ports} ) ) &&
99             ( ! defined( $args{fports} ) ) &&
100             ( ! defined( $args{lports} ) )
101             ){
102 1         11 die ('No [fl]ports key specified in the argument hash');
103             }
104 3 0 33     22 if (
      0        
      33        
      0        
      0        
105             (
106             defined( $args{ports} ) &&
107             ( ! defined( $args{ports}[0] ) )
108             ) &&
109             (
110             defined( $args{lports} ) &&
111             ( ! defined( $args{lports}[0] ) )
112             ) &&
113             (
114             defined( $args{fports} ) &&
115             ( ! defined( $args{fports}[0] ) )
116             )
117             ){
118 0         0 die ('No ports defined in the in any of the [fl]ports array');
119             }
120              
121 3         15 my $self = {
122             ports=>{},
123             fports=>{},
124             lports=>{},
125             };
126 3         7 bless $self;
127              
128             # Process the ports for matching either
129 3         5 my $ports_int=0;
130 3 50       12 if ( defined( $args{ports} ) ){
131 3         11 while (defined( $args{ports}[$ports_int] )) {
132 3 50       21 if ( $args{ports}[$ports_int] =~ /^[0-9\*]+$/ ){
133 3         32 $self->{ports}{ $args{ports}[$ports_int] }= $args{ports}[$ports_int];
134             }else{
135 0         0 my $port_number=(getservbyname( $args{ports}[$ports_int] , '' ))[2];
136              
137 0 0       0 if( !defined( $port_number ) ){
138 0         0 die("Could not resolve port '".$args{ports}[$ports_int]."' to a number");
139             }
140              
141 0         0 $self->{ports}{$port_number}=$port_number;
142             }
143              
144 3         12 $ports_int++;
145             }
146             }
147              
148             # Process the ports for matching local ports
149 3         6 $ports_int=0;
150 3 50       9 if ( defined( $args{lports} ) ){
151 3         10 while (defined( $args{lports}[$ports_int] )) {
152 3 50       16 if ( $args{lports}[$ports_int] =~ /^[0-9]+$/ ){
    0          
153 3         12 $self->{lports}{ $args{lports}[$ports_int] }= $args{lports}[$ports_int];
154             }elsif( $args{lports}[$ports_int] =~ /^\*$/ ){
155 0         0 $self->{lports}{'*'}='*';
156             }else{
157 0         0 my $port_number=(getservbyname( $args{lports}[$ports_int] , '' ))[2];
158              
159 0 0       0 if( !defined( $port_number ) ){
160 0         0 die("Could not resolve port '".$args{lports}[$ports_int]."' to a number");
161             }
162              
163 0         0 $self->{lports}{$port_number}=$port_number;
164             }
165              
166 3         9 $ports_int++;
167             }
168             }
169              
170             # Process the ports for matching foreign ports
171 3         6 $ports_int=0;
172 3 50       8 if ( defined( $args{fports} ) ){
173 3         8 while (defined( $args{fports}[$ports_int] )) {
174 3 50       12 if ( $args{fports}[$ports_int] =~ /^[0-9]+$/ ){
    0          
175 3         11 $self->{fports}{ $args{fports}[$ports_int] }= $args{fports}[$ports_int];
176             }elsif( $args{fports}[$ports_int] =~ /^\*$/ ){
177 0         0 $self->{fports}{'*'}='*';
178             }else{
179 0         0 my $port_number=(getservbyname( $args{fports}[$ports_int] , '' ))[2];
180              
181 0 0       0 if( !defined( $port_number ) ){
182 0         0 die("Could not resolve port '".$args{fports}[$ports_int]."' to a number");
183             }
184              
185 0         0 $self->{fports}{$port_number}=$port_number;
186             }
187              
188 3         30 $ports_int++;
189             }
190             }
191              
192 3         25 return $self;
193             }
194              
195             =head2 match
196              
197             Checks if a single Net::Connection object matches the stack.
198              
199             One argument is taken and that is a Net::Connection object.
200              
201             The returned value is a boolean.
202              
203             if ( $checker->match( $conn ) ){
204             print "The connection matches.\n";
205             }
206              
207             =cut
208              
209             sub match{
210 8     8 1 4018 my $self=$_[0];
211 8         16 my $object=$_[1];
212              
213 8 100       24 if ( !defined( $object ) ){
214 1         3 return 0;
215             }
216              
217 7 100       22 if ( ref( $object ) ne 'Net::Connection' ){
218 1         4 return 0;
219             }
220              
221 6         19 my $lport=$object->local_port;
222 6         35 my $fport=$object->foreign_port;
223              
224             # If either are non-numeric, resolve them if possible
225 6 50       44 if ( $lport !~ /^[0-9\*]+$/ ){
226 0         0 my $lport_number=(getservbyname( $lport , '' ))[2];
227 0 0       0 if ( defined( $lport_number ) ){
228 0         0 $lport=$lport_number;
229             }
230             }
231 6 50       21 if ( $fport !~ /^[0-9\*]+$/ ){
232 0         0 my $fport_number=(getservbyname( $fport , '' ))[2];
233 0 0       0 if ( defined( $fport_number ) ){
234 0         0 $fport=$fport_number;
235             }
236             }
237              
238             # check if this is one of the ones we are looking for
239 6 100 66     53 if (
      66        
      100        
240             defined( $self->{ports}{ $lport } ) ||
241             defined( $self->{ports}{ $fport } ) ||
242             defined( $self->{lports}{ $lport } ) ||
243             defined( $self->{fports}{ $fport } )
244             ){
245 5         27 return 1;
246             }
247              
248 1         3 return 0;
249             }
250              
251             =head1 AUTHOR
252              
253             Zane C. Bowers-Hadley, C<< >>
254              
255             =head1 BUGS
256              
257             Please report any bugs or feature requests to C, or through
258             the web interface at L. I will be notified, and then you'll
259             automatically be notified of progress on your bug as I make changes.
260              
261              
262              
263              
264             =head1 SUPPORT
265              
266             You can find documentation for this module with the perldoc command.
267              
268             perldoc Net::Connection::Match
269              
270              
271             You can also look for information at:
272              
273             =over 4
274              
275             =item * RT: CPAN's request tracker (report bugs here)
276              
277             L
278              
279             =item * AnnoCPAN: Annotated CPAN documentation
280              
281             L
282              
283             =item * CPAN Ratings
284              
285             L
286              
287             =item * Search CPAN
288              
289             L
290              
291             =back
292              
293              
294             =head1 ACKNOWLEDGEMENTS
295              
296              
297             =head1 LICENSE AND COPYRIGHT
298              
299             Copyright 2019 Zane C. Bowers-Hadley.
300              
301             This program is free software; you can redistribute it and/or modify it
302             under the terms of the the Artistic License (2.0). You may obtain a
303             copy of the full license at:
304              
305             L
306              
307             Any use, modification, and distribution of the Standard or Modified
308             Versions is governed by this Artistic License. By using, modifying or
309             distributing the Package, you accept this license. Do not use, modify,
310             or distribute the Package, if you do not accept this license.
311              
312             If your Modified Version has been derived from a Modified Version made
313             by someone other than you, you are nevertheless required to ensure that
314             your Modified Version complies with the requirements of this license.
315              
316             This license does not grant you the right to use any trademark, service
317             mark, tradename, or logo of the Copyright Holder.
318              
319             This license includes the non-exclusive, worldwide, free-of-charge
320             patent license to make, have made, use, offer to sell, sell, import and
321             otherwise transfer the Package with respect to any patent claims
322             licensable by the Copyright Holder that are necessarily infringed by the
323             Package. If you institute patent litigation (including a cross-claim or
324             counterclaim) against any party alleging that the Package constitutes
325             direct or contributory patent infringement, then this Artistic License
326             to you shall terminate on the date that such litigation is filed.
327              
328             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
329             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
330             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
331             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
332             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
333             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
334             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
335             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
336              
337              
338             =cut
339              
340             1; # End of Net::Connection::Match