File Coverage

blib/lib/Net/Connection.pm
Criterion Covered Total %
statement 58 101 57.4
branch 33 66 50.0
condition 33 54 61.1
subroutine 7 20 35.0
pod 16 16 100.0
total 147 257 57.2


line stmt bran cond sub pod time code
1             package Net::Connection;
2              
3 2     2   105374 use 5.006;
  2         14  
4 2     2   9 use strict;
  2         3  
  2         42  
5 2     2   10 use warnings;
  2         3  
  2         61  
6 2     2   867 use Net::DNS;
  2         152193  
  2         2817  
7              
8             =head1 NAME
9              
10             Net::Connection - Represents a network connection as a object.
11              
12             =head1 VERSION
13              
14             Version 0.1.0
15              
16             =cut
17              
18             our $VERSION = '0.1.0';
19              
20              
21             =head1 SYNOPSIS
22              
23             use Net::Connection;
24              
25             #create a hash ref with the desired values
26             my $args={
27             'foreign_host' => '1.2.3.4',
28             'local_host' => '4.3.2.1',
29             'foreign_port' => '22',
30             'local_port' => '11132',
31             'sendq' => '1',
32             'recvq' => '0',
33             'pid' => '34342',
34             'uid' => '1000',
35             'state' => 'ESTABLISHED',
36             'proto' => 'tcp4'
37             };
38            
39             # create the new object using the hash ref
40             my $conn=Net::Connection->new( $args );
41            
42             # the same thing, but this time resolve the UID to a username
43             $args->{'uid_resolve'}='1';
44             $conn=Net::Connection->new( $args );
45            
46             # now with PTR lookup
47             $args->{'ptrs'}='1';
48             $conn=Net::Connection->new( $args );
49            
50             # prints a bit of the connection information...
51             print "L Host:".$conn->local_host."\n".
52             "L Port:".$conn->local_host."\n".
53             "F Host:".$conn->foreign_host."\n".
54             "F Port:".$conn->foreign_host."\n";
55              
56             =head1 Methods
57              
58             =head2 new
59              
60             This initiates a new connection object.
61              
62             One argument is taken is taken and it is a hash reference.
63             The minimum number of arguements is as below.
64              
65             local_host
66             local_port
67             foreign_host
68             foreign_port
69             proto
70             state
71              
72             =head3 keys
73              
74             =head4 foreign_host
75              
76             The local host of the connection.
77              
78             This can either be a IP or hostname. Max utility is achieved via a
79             IP though as that allows PTR lookup to be done.
80              
81             If appears to be a hostname, it is copied to local_ptr and even
82             if asked to resolve PTRs it won't attempt to.
83              
84             =head4 foreign_port
85              
86             This is the foreign port of the connection.
87              
88             For best utility, using numeric here is best.
89              
90             If ports is true it will attempt to resolve it,
91             including reverse resolving if it is a port name instead.
92              
93             If ports is false or not set and this value is
94             non-numeric, it will be copied to foreign_port_name.
95              
96             =head4 foreign_port_name
97              
98             This is the name of foreign port, if one exists in the
99             service records.
100              
101             =head4 foreign_ptr
102              
103             This is the PTR address for foreign_host.
104              
105             If ptrs is not true and foreign_host appears to be
106             a hostname, then it is set to the same as foreign_host.
107              
108             =head4 local_port
109              
110             This is the local port of the connection.
111              
112             For best utility, using numeric here is best.
113              
114             If ports is true it will attempt to resolve it,
115             including reverse resolving if it is a port name instead.
116              
117             If ports is false or not set and this value is
118             non-numeric, it will be copied to local_port_name.
119              
120             =head4 local_port_name
121              
122             This is the name of local port, if one exists in the
123             service records.
124              
125             =head4 local_ptr
126              
127             This is the PTR address for local_host.
128              
129             If ptrs is not true and local_host appears to be
130             a hostname, then it is set to the same as local_host.
131              
132             =head4 pid
133              
134             This is the pid for a connection.
135              
136             If defined, it needs to be numeric.
137              
138             =head4 ports
139              
140             If true, it will attempt to resolve the port names.
141              
142             =head4 proto
143              
144             This is the protocol type.
145              
146             This needs to be defined, but unfortunately no real checking is done
147             as of currently as various OSes uses varrying capitalizations and slightly
148             different forms of TCP, TCP4, tcp4, tcpv4, and the like.
149              
150             =head4 ptrs
151              
152             If is true, then attempt to look up the PTRs for the hosts.
153              
154             =head4 recvq
155              
156             This is the recieve queue size.
157              
158             If set, it must be numeric.
159              
160             =head4 sendq
161              
162             This is the send queue size.
163              
164             If set, it must be numeric.
165              
166             =head4 state
167              
168             This is the current state of the connection.
169              
170             This needs to be defined, but unfortunately no real checking is
171             done as of currently as there are minor naming differences between
172             OSes as well as some including states that are not found in others.
173              
174             =head4 uid
175              
176             The UID is the of the user the has the connection open.
177              
178             This must be numeric.
179              
180             If uid_resolve is set to true then the UID will be resolved
181             and stored in username.
182              
183             If this is not defined, uid_resolve is true, and username is defined
184             then it will attempt to resolve the UID from the username.
185              
186             =head4 uid_resolve
187              
188             If set to true and uid is given, then a attempt will be made to
189             resolve the UID to a username.
190              
191             =head4 username
192              
193             This is the username for a connection.
194              
195             If uid_resolve is true and uid is defined, then this
196             will attempt to be automatically contemplated.
197              
198             If uid_resolve is true and uid is defined, then this
199             will attempt to be automatically contemplated.
200              
201             =cut
202              
203             sub new{
204 16     16 1 4081 my %args;
205 16 50       34 if(defined($_[1])){
206 16         23 %args= %{$_[1]};
  16         86  
207             };
208              
209             # make sure we got the required bits
210 16 100 100     122 if (
      100        
      100        
      100        
      100        
211             (!defined( $args{'foreign_host'}) ) ||
212             (!defined( $args{'local_host'}) ) ||
213             (!defined( $args{'foreign_port'}) ) ||
214             (!defined( $args{'local_port'}) ) ||
215             (!defined( $args{'state'}) ) ||
216             (!defined( $args{'proto'}) )
217             ){
218 7         49 die "One or more of the required arguments is not defined";
219             }
220              
221             # PID must be numeric if given
222 9 100 100     42 if (
223             defined( $args{'pid'} ) &&
224             ( $args{'pid'} !~ /^[0-9]+$/ )
225             ){
226 1         7 die '$args{"pid"} is not numeric';
227             }
228              
229             # UID must be numeric if given
230 8 100 100     25 if (
231             defined( $args{'uid'} ) &&
232             ( $args{'uid'} !~ /^[0-9]+$/ )
233             ){
234 1         8 die '$args{"uid"} is not numeric';
235             }
236              
237             # set the sendq/recvq and make sure they are numeric if given
238 7 100 66     34 if (
239             defined( $args{'sendq'} ) &&
240             ( $args{'sendq'} !~ /^[0-9]+$/ )
241             ){
242 1         8 die '$args{"sendq"} is not numeric';
243             }
244 6 100 66     22 if (
245             defined( $args{'recvq'} ) &&
246             ( $args{'recvq'} !~ /^[0-9]+$/ )
247             ){
248 1         8 die '$args{"recvq"} is not numeric';
249             }
250              
251             my $self={
252             'foreign_host' => $args{'foreign_host'},
253             'local_host' => $args{'local_host'},
254             'foreign_port' => $args{'foreign_port'},
255             'foreign_port_name' => $args{'foreign_port_name'},
256             'local_port' => $args{'local_port'},
257             'local_port_name' => $args{'local_port_name'},
258             'sendq' => undef,
259             'recvq' => undef,
260             'pid' => undef,
261             'uid' => undef,
262             'username' => undef,
263             'state' => $args{'state'},
264 5         34 'proto' => $args{'proto'},
265             'local_ptr' => undef,
266             'foreign_ptr' => undef,
267             };
268 5         8 bless $self;
269              
270             # Set these if defined
271 5 50       9 if (defined( $args{'sendq'} )){
272 5         10 $self->{'sendq'}=$args{'sendq'};
273             }
274 5 50       11 if (defined( $args{'recvq'} )){
275 5         6 $self->{'recvq'}=$args{'recvq'};
276             }
277 5 50       10 if (defined( $args{'local_ptr'} )){
278 0         0 $self->{'local_ptr'}=$args{'local_ptr'};
279             }
280 5 50       7 if (defined( $args{'foreign_ptr'} )){
281 0         0 $self->{'foreign_ptr'}=$args{'foreign_ptr'};
282             }
283 5 100       9 if (defined( $args{'uid'} )){
284 2         3 $self->{'uid'}=$args{'uid'};
285             }
286 5 100       8 if (defined( $args{'pid'} )){
287 4         5 $self->{'pid'}=$args{'pid'};
288             }
289 5 100       9 if (defined( $args{'username'} )){
290 1         3 $self->{'username'}=$args{'username'};
291             }
292              
293             # resolve port names if asked to
294 5 50       9 if ( $args{ports} ){
295             # If the port is non-numeric, set the name and attempt to resolve it.
296 0 0       0 if ( $self->{'local_port'} =~ /[A-Za-z]/ ){
    0          
297 0         0 $self->{'local_port_name'}=$self->{'local_port'};
298 0         0 my $service=getservbyname($self->{'local_port_name'}, undef);
299 0 0       0 if (defined( $service )){
300 0         0 $self->{'local_port'}=$service;
301             }
302             }elsif( $self->{'local_port'} =~ /^[0-9]+$/ ){
303 0         0 $self->{'local_port_name'}=getservbyport( $self->{'local_port'}, 'tcp' );
304             }
305 0 0       0 if ( $self->{'foreign_port'} =~ /[A-Za-z]/ ){
    0          
306 0         0 $self->{'foreign_port_name'}=$self->{'foreign_port'};
307 0         0 my $service=getservbyname($self->{'foreign_port_name'}, undef);
308 0 0       0 if (defined( $service )){
309 0         0 $self->{'foreign_port'}=$service;
310             }
311             }elsif( $self->{'foreign_port'} =~ /^[0-9]+$/ ){
312 0         0 $self->{'foreign_port_name'}=getservbyport( $self->{'foreign_port'}, 'tcp' );
313             }
314             }else{
315             # If the port is non-numeric, set it as the port name
316 5 50       26 if ( $self->{'local_port'} =~ /[A-Za-z]/ ){
317 0         0 $self->{'local_port_name'}=$self->{'local_port'};
318             }
319 5 50       37 if ( $self->{'foreign_port'} =~ /[A-Za-z]/ ){
320 0         0 $self->{'foreign_port_name'}=$self->{'foreign_port'};
321             }
322             }
323              
324 5         28 my $dns=Net::DNS::Resolver->new;
325              
326             # resolve PTRs if asked to
327 5 50 33     709 if (
328             defined( $args{ptrs} ) &&
329             $args{ptrs}
330             ){
331             # process foreign_host
332 0 0 0     0 if (
333             ( $self->{'foreign_host'} =~ /[A-Za-z]/ ) &&
334             ( $self->{'foreign_host'} !~ /\:/ )
335             ){
336             # appears to be a hostname already
337 0         0 $self->{'foreign_ptr'}=$self->{'foreign_host'};
338             }else{
339             # attempt to resolve it
340 0         0 eval{
341 0         0 my $answer=$dns->search( $self->{'foreign_host'} );
342 0 0 0     0 if ( defined( $answer->{answer}[0] ) &&
343             ( ref( $answer->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
344             ){
345 0         0 $self->{'foreign_ptr'}=lc($answer->{answer}[0]->ptrdname);
346             }
347             }
348             }
349             # process local_host
350 0 0 0     0 if (
351             ( $self->{'local_host'} =~ /[A-Za-z]/ ) &&
352             ( $self->{'local_host'} !~ /\:/ )
353             ){
354             # appears to be a hostname already
355 0         0 $self->{'local_ptr'}=$self->{'local_host'};
356             }else{
357             # attempt to resolve it
358 0         0 eval{
359 0         0 my $answer=$dns->search( $self->{'local_host'} );
360 0 0 0     0 if ( defined( $answer->{answer}[0] ) &&
361             ( ref( $answer->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
362             ){
363 0         0 $self->{'local_ptr'}=lc($answer->{answer}[0]->ptrdname);
364             }
365             }
366             }
367             }else{
368             # We are not doing auto PTR resolving...
369             # just set them if it appears to be a hostname
370 5 50 33     16 if (
371             ( $self->{'foreign_host'} =~ /[A-Za-z]/ ) &&
372             ( $self->{'foreign_host'} !~ /\:/ )
373             ){
374 0         0 $self->{'foreign_ptr'}=$self->{'foreign_host'};
375             }
376 5 50 33     20 if (
377             ( $self->{'local_host'} =~ /[A-Za-z]/ ) &&
378             ( $self->{'local_host'} !~ /\:/ )
379             ){
380 0         0 $self->{'local_ptr'}=$self->{'local_host'};
381             }
382             }
383              
384             # resolve the UID/username if asked
385 5 100 100     23 if (
    100 66        
386             $args{'uid_resolve'} &&
387             defined( $self->{'uid'} )
388             ){
389 1         3 eval{
390 1         555 my @pwline=getpwuid( $self->{'uid'} );
391 1 50       6 if ( defined( $pwline[0] ) ){
392 1         5 $self->{'username'}=$pwline[0];
393             }
394             }
395             }elsif (
396             $args{'uid_resolve'} &&
397             ( ! defined( $self->{'uid'} ) )
398             ){
399 1         2 eval{
400 1         81 my @pwline=getpwnam( $self->{'username'} );
401 1 50       6 if ( defined( $pwline[2] ) ){
402 1         4 $self->{'uid'}=$pwline[2];
403             }
404             }
405             }
406              
407 5         50 return $self;
408             }
409              
410             =head2 foreign_host
411              
412             Returns the foreign host.
413              
414             my $f_host=$conn->foreign_host;
415              
416             =cut
417              
418             sub foreign_host{
419 0     0 1 0 return $_[0]->{'foreign_host'};
420             }
421              
422             =head2 foreign_port
423              
424             This returns the foreign port.
425              
426             my $f_port=$conn->foreign_port;
427              
428             =cut
429              
430             sub foreign_port{
431 0     0 1 0 return $_[0]->{'foreign_port'};
432             }
433              
434             =head2 foreign_port_name
435              
436             This returns the foreign port name.
437              
438             This may potentially return undef if one is
439             not set/unknown.
440              
441             my $f_port=$conn->foreign_port;
442              
443             =cut
444              
445             sub foreign_port_name{
446 0     0 1 0 return $_[0]->{'foreign_port_name'};
447             }
448              
449             =head2 foreign_ptr
450              
451             This returns the PTR for the foreign host.
452              
453             If one was not supplied or if it could not be found
454             if resolving was enabled then undef will be returned.
455              
456             my $f_ptr=$conn->foreign_ptr;
457              
458             =cut
459              
460             sub foreign_ptr{
461 0     0 1 0 return $_[0]->{'foreign_ptr'};
462             }
463              
464             =head2 local_host
465              
466             Returns the local host.
467              
468             my $l_host=$conn->local_host;
469              
470             =cut
471              
472             sub local_host{
473 0     0 1 0 return $_[0]->{'local_host'};
474             }
475              
476             =head2 local_port
477              
478             This returns the local port.
479              
480             my $l_port=$conn->local_port;
481              
482             =cut
483              
484             sub local_port{
485 0     0 1 0 return $_[0]->{'local_port'};
486             }
487              
488             =head2 local_port_name
489              
490             This returns the local port name.
491              
492             This may potentially return undef if one is
493             not set/unknown.
494              
495             my $l_port=$conn->local_port;
496              
497             =cut
498              
499             sub local_port_name{
500 0     0 1 0 return $_[0]->{'local_port_name'};
501             }
502              
503             =head2 foreign_ptr
504              
505             This returns the PTR for the local host.
506              
507             If one was not supplied or if it could not be found
508             if resolving was enabled then undef will be returned.
509              
510             my $l_ptr=$conn->local_ptr;
511              
512             =cut
513              
514             sub local_ptr{
515 0     0 1 0 return $_[0]->{'local_ptr'};
516             }
517              
518             =head2 pid
519              
520             This returns the pid of a connection.
521              
522             This may return undef.
523              
524             my $pid=$conn->pid;
525              
526             =cut
527              
528             sub pid{
529 0     0 1 0 return $_[0]->{'pid'};
530             }
531              
532             =head2 proto
533              
534             Returns the protocol in use by the connection.
535              
536             Please note this value with vary slightly between OSes.
537              
538             my $proto=$conn->proto;
539              
540             =cut
541              
542             sub proto{
543 0     0 1 0 return $_[0]->{'proto'};
544             }
545              
546             =head2 recvq
547              
548             Returns the size of the recieve queue the connection.
549              
550             This may return undef.
551              
552             my $recvq=$conn->recvq;
553              
554             =cut
555              
556             sub recvq{
557 0     0 1 0 return $_[0]->{'recvq'};
558             }
559              
560              
561             =head2 sendq
562              
563             Returns the size of the send queue the connection.
564              
565             This may return undef.
566              
567             my $sendq=$conn->sendq;
568              
569             =cut
570              
571             sub sendq{
572 0     0 1 0 return $_[0]->{'sendq'};
573             }
574              
575             =head2 state
576              
577             Returns the state the connection is currently in.
578              
579             Please note this value with vary slightly between OSes.
580              
581             my $state=$conn->state;
582              
583             =cut
584              
585             sub state{
586 0     0 1 0 return $_[0]->{'state'};
587             }
588              
589             =head2 uid
590              
591             Returns the UID that has the connection.
592              
593             This may not be if it was not set. Please see new
594             for more information.
595              
596             my $uid=$conn->uid;
597              
598             =cut
599              
600             sub uid{
601 2     2 1 8 return $_[0]->{'uid'};
602             }
603              
604             =head2 username
605              
606             Returns the username that has the connection.
607              
608             This may not be if it was not set. Please see new
609             for more information.
610              
611             my $username=$conn->username;
612              
613             =cut
614              
615             sub username{
616 2     2 1 9 return $_[0]->{'username'};
617             }
618              
619             =head1 AUTHOR
620              
621             Zane C. Bowers-Hadley, C<< >>
622              
623             =head1 BUGS
624              
625             Please report any bugs or feature requests to C, or through
626             the web interface at L. I will be notified, and then you'll
627             automatically be notified of progress on your bug as I make changes.
628              
629              
630              
631              
632             =head1 SUPPORT
633              
634             You can find documentation for this module with the perldoc command.
635              
636             perldoc Net::Connection
637              
638              
639             You can also look for information at:
640              
641             =over 4
642              
643             =item * RT: CPAN's request tracker (report bugs here)
644              
645             L
646              
647             =item * AnnoCPAN: Annotated CPAN documentation
648              
649             L
650              
651             =item * CPAN Ratings
652              
653             L
654              
655             =item * Search CPAN
656              
657             L
658              
659             =item * Repository
660              
661             L
662              
663             =back
664              
665              
666             =head1 ACKNOWLEDGEMENTS
667              
668              
669             =head1 LICENSE AND COPYRIGHT
670              
671             This software is Copyright (c) 2019 by Zane C. Bowers-Hadley.
672              
673             This is free software, licensed under:
674              
675             The Artistic License 2.0 (GPL Compatible)
676              
677              
678             =cut
679              
680             1; # End of Net::Connection