File Coverage

blib/lib/Net/addrinfo.pm
Criterion Covered Total %
statement 17 97 17.5
branch 0 50 0.0
condition 0 3 0.0
subroutine 5 19 26.3
pod 0 11 0.0
total 22 180 12.2


line stmt bran cond sub pod time code
1             #
2             # addrinfo.pm -- Perl 5 interface to getaddrinfo(3) and related structs
3             #
4             # written by G. S. Marzot (marz@users.sourceforge.net)
5             #
6             # Copyright (c) 2006-2009 G. S. Marzot. All rights reserved.
7             #
8             # Copyright (c) 2006-2009 SPARTA, Inc. All rights reserved.
9             #
10             # This program is free software; you can redistribute it and/or
11             # modify it under the same terms as Perl itself.
12             #
13             package Net::addrinfo;
14 1     1   11423 use Socket qw(:all);
  1         10432  
  1         1812  
15 1     1   13 use Carp;
  1         2  
  1         81  
16              
17             our $VERSION = '1.02'; # current release version number
18              
19 1     1   5 use Exporter;
  1         6  
  1         41  
20 1     1   5 use DynaLoader;
  1         1  
  1         1386  
21              
22             sub AUTOLOAD {
23 0     0   0 my $sub = $AUTOLOAD;
24 0         0 (my $constname = $sub) =~ s/.*:://;
25              
26 0 0       0 my $val = (exists $LOCAL_CONSTANTS{$constname} ?
27             $LOCAL_CONSTANTS{$constname} : constant($constname));
28 0 0       0 if (not defined $val) {
29 0         0 croak "Your vendor has not defined constant $constname";
30             }
31 0     0   0 *$sub = sub { $val }; # same as: eval "sub $sub { $val }";
  0         0  
32 0         0 goto &$sub;
33             }
34              
35             our @ISA = qw(Exporter DynaLoader);
36              
37             # our @EXPORT = qw( getaddrinfo );
38              
39             our @AI_FLAGS = qw(AI_NUMERICHOST AI_NUMERICSERV AI_PASSIVE AI_V4MAPPED AI_ADDRCONFIG AI_ALL AI_CANONIDN AI_CANONNAME AI_IDN AI_IDN_ALLOW_UNASSIGNED AI_IDN_USE_STD3_ASCII_RULES);
40              
41             #hack to make up for missing constants - should be provided with 'Socket'
42             our %LOCAL_CONSTANTS = qw(IPPROTO_IP 0 IPPROTO_HOPOPTS 0 IPPROTO_ICMP 1 IPPROTO_IGMP 2 IPPROTO_IPIP 4 IPPROTO_EGP 8 IPPROTO_PUP 12 IPPROTO_UDP 17 IPPROTO_IDP 22 IPPROTO_TP 29 IPPROTO_IPV6 41 IPPROTO_ROUTING 43 IPPROTO_FRAGMENT 44 IPPROTO_RSVP 46 IPPROTO_GRE 47 IPPROTO_ESP 50 IPPROTO_AH 51 IPPROTO_ICMPV6 58 IPPROTO_NONE 59 IPPROTO_RAW 255 IPPROTO_DSTOPTS 60 IPPROTO_MTP 92 IPPROTO_ENCAP 98 IPPROTO_PIM 103 IPPROTO_COMP 108 IPPROTO_SCTP 132);
43              
44             our @EXPORT = qw(getaddrinfo gai_strerror AI_ADDRCONFIG AI_ALL AI_CANONIDN AI_CANONNAME AI_IDN AI_IDN_ALLOW_UNASSIGNED AI_IDN_USE_STD3_ASCII_RULES AI_NUMERICHOST AI_NUMERICSERV AI_PASSIVE AI_V4MAPPED EAI_ADDRFAMILY EAI_AGAIN EAI_ALLDONE EAI_BADFLAGS EAI_CANCELED EAI_FAIL EAI_FAMILY EAI_IDN_ENCODE EAI_INPROGRESS EAI_INTR EAI_MEMORY EAI_NODATA EAI_NONAME EAI_NOTCANCELED EAI_OVERFLOW EAI_SERVICE EAI_SOCKTYPE EAI_SYSTEM GAI_NOWAIT GAI_WAIT NI_DGRAM NI_IDN NI_IDN_ALLOW_UNASSIGNED NI_IDN_USE_STD3_ASCII_RULES NI_MAXHOST NI_MAXSERV NI_NAMEREQD NI_NOFQDN NI_NUMERICHOST NI_NUMERICSERV IPPROTO_IP IPPROTO_HOPOPTS IPPROTO_ICMP IPPROTO_IGMP IPPROTO_IPIP IPPROTO_EGP IPPROTO_PUP IPPROTO_UDP IPPROTO_IDP IPPROTO_TP IPPROTO_IPV6 IPPROTO_ROUTING IPPROTO_FRAGMENT IPPROTO_RSVP IPPROTO_GRE IPPROTO_ESP IPPROTO_AH IPPROTO_ICMPV6 IPPROTO_NONE IPPROTO_RAW IPPROTO_DSTOPTS IPPROTO_MTP IPPROTO_ENCAP IPPROTO_PIM IPPROTO_COMP IPPROTO_SCTP);
45              
46             bootstrap Net::addrinfo;
47              
48             sub new {
49 8     8 0 427019 my $type = shift;
50 8         62 my $self = {flags=>0, family=>0, socktype=>0, protocol=>0, addrlen=>0,
51             addr=>undef, cannonname=>undef};
52 8         35 my %params = @_;
53 8         36 @$self{keys %params} = values %params;
54              
55 8         61 bless $self, $type;
56             }
57              
58             sub flags {
59 0     0 0   my $self = shift;
60              
61 0 0         if (@_) {
62 0           $self->{flags} = scalar(shift);
63             }
64 0           return $self->{flags};
65             }
66              
67             sub family {
68 0     0 0   my $self = shift;
69              
70 0 0         if (@_) {
71 0           $self->{family} = int(shift);
72             }
73 0           return $self->{family};
74             }
75              
76             sub socktype {
77 0     0 0   my $self = shift;
78              
79 0 0         if (@_) {
80 0           $self->{socktype} = int(shift);
81             }
82 0           return $self->{socktype};
83             }
84              
85             sub protocol {
86 0     0 0   my $self = shift;
87              
88 0 0         if (@_) {
89 0           $self->{protocol} = int(shift);
90             }
91 0           return $self->{protocol};
92             }
93              
94             sub addrlen {
95 0     0 0   my $self = shift;
96              
97 0 0         if (@_) {
98 0           $self->{addrlen} = int(shift);
99             }
100              
101 0           return $self->{addrlen};
102             }
103              
104             sub addr {
105 0     0 0   my $self = shift;
106              
107 0 0         if (@_) {
108 0           $self->{addr} = scalar(shift);
109             }
110 0           return $self->{addr};
111             }
112              
113             sub canonname {
114 0     0 0   my $self = shift;
115              
116 0 0         if (@_) {
117 0           $self->{canonname} = scalar(shift);
118             }
119 0           return $self->{canonname};
120             }
121              
122             # special accessor sub for val_addrinfo structures in support of DNSSEC
123             # note: not present ot relevant for non-DNSSEC applications
124             sub val_status {
125 0     0 0   my $self = shift;
126              
127 0 0         if (@_) {
128 0           $self->{val_status} = scalar(shift);
129             }
130 0           return $self->{val_status};
131             }
132              
133             sub stringify {
134 0     0 0   my $self = shift;
135 0           my $dstr;
136              
137 0           $dstr .= "{\n";
138 0           my $flags = join('|',grep {$self->flags & eval("\&$_;");}@AI_FLAGS);
  0            
139 0           $dstr .= "\tai_flags = ($flags)\n";
140 0           my $family = $self->family;
141 0 0         $family = (($family == AF_UNSPEC) ? "AF_UNSPEC" :
    0          
    0          
142             (($family == AF_INET) ? "AF_INET" :
143             (($family == AF_INET6) ? "AF_INET6" : "Unknown")));
144 0           $dstr .= "\tai_family = $family\n";
145 0           my $socktype = $self->socktype;
146 0 0         $socktype = (($socktype == SOCK_STREAM) ? "SOCK_STREAM" :
    0          
    0          
147             (($socktype == SOCK_DGRAM) ? "SOCK_DGRAM" :
148             (($socktype == SOCK_RAW) ? "SOCK_RAW" : "Unknown")));
149 0           $dstr .= "\tai_socktype = $socktype\n";
150 0           my $protocol = $self->protocol;
151              
152 0 0         $protocol = (($protocol == IPPROTO_UDP()) ? "IPPROTO_UDP" :
    0          
    0          
153             (($protocol == IPPROTO_TCP) ? "IPPROTO_TCP" :
154             (($protocol == IPPROTO_IP()) ? "IPPROTO_IP" : "Unknown")));
155 0           $dstr .= "\tai_protocol = $protocol\n";
156 0   0       my $addrlen = $self->addrlen || length($self->addr);
157 0           $dstr .= "\tai_addrlen = $addrlen\n";
158 0           my $addr;
159 0 0         if ($self->addr) {
160 0 0         if ($self->family == AF_INET) {
161 0           my ($port,$iaddr) = unpack_sockaddr_in($self->addr);
162 0           $addr = "($port, " . inet_ntoa($iaddr) . ")";
163             # } elsif ($self->family == AF_INET6) {
164             #
165             # XXX needs implementation
166             } else {
167 0           $addr = "0x" . unpack("H*",$self->addr);
168             }
169             }
170 0           $dstr .= "\tai_addr = $addr\n";
171 0 0         my $canonname = (defined $self->canonname ? $self->canonname : "");
172 0           $dstr .= "\tai_canonname = $canonname\n";
173 0 0         if (exists $self->{val_status}) {
174 0           my $val_status = $self->val_status;
175 0           $dstr .= "\tai_val_status = $val_status\n";
176             }
177 0           $dstr .= "}\n";
178            
179 0           return $dstr;
180             }
181              
182              
183             sub getaddrinfo {
184 0     0     my $node = shift;
185 0           my $service = shift;
186 0           my $hints = shift;
187              
188 0           my $result = Net::addrinfo::_getaddrinfo($node, $service, $hints);
189            
190 0 0         $result = [$result] unless ref $result eq 'ARRAY';
191            
192 0 0         return (wantarray ? @$result : shift(@$result));
193             }
194              
195             sub gai_strerror {
196 0     0 0   my $errstr = Net::addrinfo::_gai_strerror(@_);
197              
198 0           return $errstr;
199             }
200              
201 0     0     sub DESTROY {
202             # print STDERR "addrinfo:DESTROY\n";
203             }
204              
205             1;
206             __END__