File Coverage

blib/lib/Net/Connection.pm
Criterion Covered Total %
statement 58 98 59.1
branch 33 62 53.2
condition 33 54 61.1
subroutine 7 19 36.8
pod 15 15 100.0
total 146 248 58.8


line stmt bran cond sub pod time code
1             package Net::Connection;
2              
3 2     2   132719 use 5.006;
  2         16  
4 2     2   11 use strict;
  2         4  
  2         52  
5 2     2   13 use warnings;
  2         3  
  2         67  
6 2     2   1147 use Net::DNS;
  2         189710  
  2         3211  
7              
8             =head1 NAME
9              
10             Net::Connection - Represents a network connection as a object.
11              
12             =head1 VERSION
13              
14             Version 0.0.0
15              
16             =cut
17              
18             our $VERSION = '0.0.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 5042 my %args;
205 16 50       39 if(defined($_[1])){
206 16         24 %args= %{$_[1]};
  16         111  
207             };
208              
209             # make sure we got the required bits
210 16 100 100     156 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         60 die "One or more of the required arguments is not defined";
219             }
220              
221             # PID must be numeric if given
222 9 100 100     51 if (
223             defined( $args{'pid'} ) &&
224             ( $args{'pid'} !~ /^[0-9]+$/ )
225             ){
226 1         9 die '$args{"pid"} is not numeric';
227             }
228              
229             # UID must be numeric if given
230 8 100 100     28 if (
231             defined( $args{'uid'} ) &&
232             ( $args{'uid'} !~ /^[0-9]+$/ )
233             ){
234 1         10 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     41 if (
239             defined( $args{'sendq'} ) &&
240             ( $args{'sendq'} !~ /^[0-9]+$/ )
241             ){
242 1         11 die '$args{"sendq"} is not numeric';
243             }
244 6 100 66     32 if (
245             defined( $args{'recvq'} ) &&
246             ( $args{'recvq'} !~ /^[0-9]+$/ )
247             ){
248 1         10 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         39 'proto' => $args{'proto'},
265             'local_ptr' => undef,
266             'foreign_ptr' => undef,
267             };
268 5         10 bless $self;
269              
270             # Set these if defined
271 5 50       13 if (defined( $args{'sendq'} )){
272 5         14 $self->{'sendq'}=$args{'sendq'};
273             }
274 5 50       10 if (defined( $args{'recvq'} )){
275 5         8 $self->{'recvq'}=$args{'recvq'};
276             }
277 5 50       25 if (defined( $args{'local_ptr'} )){
278 0         0 $self->{'local_ptr'}=$args{'local_ptr'};
279             }
280 5 50       11 if (defined( $args{'foreign_ptr'} )){
281 0         0 $self->{'foreign_ptr'}=$args{'foreign_ptr'};
282             }
283 5 100       10 if (defined( $args{'uid'} )){
284 2         4 $self->{'uid'}=$args{'uid'};
285             }
286 5 100       10 if (defined( $args{'pid'} )){
287 4         7 $self->{'pid'}=$args{'pid'};
288             }
289 5 100       11 if (defined( $args{'username'} )){
290 1         3 $self->{'username'}=$args{'username'};
291             }
292              
293             # resolve port names if asked to
294 5 50       12 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]/ ){
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             }
303 0 0       0 if ( $self->{'foreign_port'} =~ /[A-Za-z]/ ){
304 0         0 $self->{'foreign_port_name'}=$self->{'foreign_port'};
305 0         0 my $service=getservbyname($self->{'foreign_port_name'}, undef);
306 0 0       0 if (defined( $service )){
307 0         0 $self->{'foreign_port'}=$service;
308             }
309             }
310             }else{
311             # If the port is non-numeric, set it as the port name
312 5 50       24 if ( $self->{'local_port'} =~ /[A-Za-z]/ ){
313 0         0 $self->{'local_port_name'}=$self->{'local_port'};
314             }
315 5 50       43 if ( $self->{'foreign_port'} =~ /[A-Za-z]/ ){
316 0         0 $self->{'foreign_port_name'}=$self->{'foreign_port'};
317             }
318             }
319              
320 5         38 my $dns=Net::DNS::Resolver->new;
321              
322             # resolve PTRs if asked to
323 5 50 33     930 if (
324             defined( $args{ptrs} ) &&
325             $args{ptrs}
326             ){
327             # process foreign_host
328 0 0 0     0 if (
329             ( $self->{'foreign_host'} =~ /[A-Za-z]/ ) &&
330             ( $self->{'foreign_host'} !~ /\:/ )
331             ){
332             # appears to be a hostname already
333 0         0 $self->{'foreign_ptr'}=$self->{'foreign_host'};
334             }else{
335             # attempt to resolve it
336 0         0 eval{
337 0         0 my $answer=$dns->search( $self->{'foreign_host'} );
338 0 0 0     0 if ( defined( $answer->{answer}[0] ) &&
339             ( ref( $answer->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
340             ){
341 0         0 $self->{'foreign_ptr'}=lc($answer->{answer}[0]->ptrdname);
342             }
343             }
344             }
345             # process local_host
346 0 0 0     0 if (
347             ( $self->{'local_host'} =~ /[A-Za-z]/ ) &&
348             ( $self->{'local_host'} !~ /\:/ )
349             ){
350             # appears to be a hostname already
351 0         0 $self->{'local_ptr'}=$self->{'local_host'};
352             }else{
353             # attempt to resolve it
354 0         0 eval{
355 0         0 my $answer=$dns->search( $self->{'local_host'} );
356 0 0 0     0 if ( defined( $answer->{answer}[0] ) &&
357             ( ref( $answer->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
358             ){
359 0         0 $self->{'local_ptr'}=lc($answer->{answer}[0]->ptrdname);
360             }
361             }
362             }
363             }else{
364             # We are not doing auto PTR resolving...
365             # just set them if it appears to be a hostname
366 5 50 33     19 if (
367             ( $self->{'foreign_host'} =~ /[A-Za-z]/ ) &&
368             ( $self->{'foreign_host'} !~ /\:/ )
369             ){
370 0         0 $self->{'foreign_ptr'}=$self->{'foreign_host'};
371             }
372 5 50 33     14 if (
373             ( $self->{'local_host'} =~ /[A-Za-z]/ ) &&
374             ( $self->{'local_host'} !~ /\:/ )
375             ){
376 0         0 $self->{'local_ptr'}=$self->{'local_host'};
377             }
378             }
379              
380             # resolve the UID/username if asked
381 5 100 100     38 if (
    100 66        
382             $args{'uid_resolve'} &&
383             defined( $self->{'uid'} )
384             ){
385 1         2 eval{
386 1         713 my @pwline=getpwuid( $self->{'uid'} );
387 1 50       8 if ( defined( $pwline[0] ) ){
388 1         5 $self->{'username'}=$pwline[0];
389             }
390             }
391             }elsif (
392             $args{'uid_resolve'} &&
393             ( ! defined( $self->{'uid'} ) )
394             ){
395 1         4 eval{
396 1         101 my @pwline=getpwnam( $self->{'username'} );
397 1 50       7 if ( defined( $pwline[2] ) ){
398 1         5 $self->{'uid'}=$pwline[2];
399             }
400             }
401             }
402              
403 5         59 return $self;
404             }
405              
406             =head2 foreign_host
407              
408             Returns the foreign host.
409              
410             my $f_host=$conn->foreign_host;
411              
412             =cut
413              
414             sub foreign_host{
415 0     0 1 0 return $_[0]->{'foreign_host'};
416             }
417              
418             =head2 foreign_port
419              
420             This returns the foreign port.
421              
422             my $f_port=$conn->foreign_port;
423              
424             =cut
425              
426             sub foreign_port{
427 0     0 1 0 return $_[0]->{'foreign_port'};
428             }
429              
430             =head2 foreign_port_name
431              
432             This returns the foreign port name.
433              
434             This may potentially return undef if one is
435             not set/unknown.
436              
437             my $f_port=$conn->foreign_port;
438              
439             =cut
440              
441             sub foreign_port_name{
442 0     0 1 0 return $_[0]->{'foreign_port_name'};
443             }
444              
445             =head2 foreign_ptr
446              
447             This returns the PTR for the foreign host.
448              
449             If one was not supplied or if it could not be found
450             if resolving was enabled then undef will be returned.
451              
452             my $f_ptr=$conn-
453              
454             =cut
455              
456             sub foreign_ptr{
457 0     0 1 0 return $_[0]->{'foreign_ptr'};
458             }
459              
460             =head2 local_host
461              
462             Returns the local host.
463              
464             my $l_host=$conn->local_host;
465              
466             =cut
467              
468             sub local_host{
469 0     0 1 0 return $_[0]->{'local_host'};
470             }
471              
472             =head2 local_port
473              
474             This returns the local port.
475              
476             my $l_port=$conn->local_port;
477              
478             =cut
479              
480             sub local_port{
481 0     0 1 0 return $_[0]->{'local_port'};
482             }
483              
484             =head2 local_port_name
485              
486             This returns the local port name.
487              
488             This may potentially return undef if one is
489             not set/unknown.
490              
491             my $l_port=$conn->local_port;
492              
493             =cut
494              
495             sub local_port_name{
496 0     0 1 0 return $_[0]->{'local_port_name'};
497             }
498              
499             =head2 foreign_ptr
500              
501             This returns the PTR for the local host.
502              
503             If one was not supplied or if it could not be found
504             if resolving was enabled then undef will be returned.
505              
506             my $l_ptr=$conn->local_ptr;
507              
508             =cut
509              
510             sub local_ptr{
511 0     0 1 0 return $_[0]->{'local_ptr'};
512             }
513              
514             =head2 proto
515              
516             Returns the protocol in use by the connection.
517              
518             Please note this value with vary slightly between OSes.
519              
520             my $proto=$conn->proto;
521              
522             =cut
523              
524             sub proto{
525 0     0 1 0 return $_[0]->{'proto'};
526             }
527              
528             =head2 recvq
529              
530             Returns the size of the recieve queue the connection.
531              
532             This may return undef.
533              
534             my $recvq=$conn->recvq;
535              
536             =cut
537              
538             sub recvq{
539 0     0 1 0 return $_[0]->{'recvq'};
540             }
541              
542              
543             =head2 sendq
544              
545             Returns the size of the send queue the connection.
546              
547             This may return undef.
548              
549             my $sendq=$conn->sendq;
550              
551             =cut
552              
553             sub sendq{
554 0     0 1 0 return $_[0]->{'sendq'};
555             }
556              
557             =head2 state
558              
559             Returns the state the connection is currently in.
560              
561             Please note this value with vary slightly between OSes.
562              
563             my $state=$conn->state;
564              
565             =cut
566              
567             sub state{
568 0     0 1 0 return $_[0]->{'state'};
569             }
570              
571             =head2 uid
572              
573             Returns the UID that has the connection.
574              
575             This may not be if it was not set. Please see new
576             for more information.
577              
578             my $uid=$conn->uid;
579              
580             =cut
581              
582             sub uid{
583 2     2 1 11 return $_[0]->{'uid'};
584             }
585              
586             =head2 username
587              
588             Returns the username that has the connection.
589              
590             This may not be if it was not set. Please see new
591             for more information.
592              
593             my $username=$conn->username;
594              
595             =cut
596              
597             sub username{
598 2     2 1 13 return $_[0]->{'username'};
599             }
600              
601             =head1 AUTHOR
602              
603             Zane C. Bowers-Hadley, C<< >>
604              
605             =head1 BUGS
606              
607             Please report any bugs or feature requests to C, or through
608             the web interface at L. I will be notified, and then you'll
609             automatically be notified of progress on your bug as I make changes.
610              
611              
612              
613              
614             =head1 SUPPORT
615              
616             You can find documentation for this module with the perldoc command.
617              
618             perldoc Net::Connection
619              
620              
621             You can also look for information at:
622              
623             =over 4
624              
625             =item * RT: CPAN's request tracker (report bugs here)
626              
627             L
628              
629             =item * AnnoCPAN: Annotated CPAN documentation
630              
631             L
632              
633             =item * CPAN Ratings
634              
635             L
636              
637             =item * Search CPAN
638              
639             L
640              
641             =item * Repository
642              
643             L
644              
645             =back
646              
647              
648             =head1 ACKNOWLEDGEMENTS
649              
650              
651             =head1 LICENSE AND COPYRIGHT
652              
653             This software is Copyright (c) 2019 by Zane C. Bowers-Hadley.
654              
655             This is free software, licensed under:
656              
657             The Artistic License 2.0 (GPL Compatible)
658              
659              
660             =cut
661              
662             1; # End of Net::Connection