File Coverage

blib/lib/Net/IRR.pm
Criterion Covered Total %
statement 97 128 75.7
branch 26 70 37.1
condition 6 19 31.5
subroutine 22 26 84.6
pod 14 14 100.0
total 165 257 64.2


line stmt bran cond sub pod time code
1             package Net::IRR;
2              
3 1     1   68943 use strict;
  1         3  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         23  
5              
6 1     1   5 use Carp;
  1         2  
  1         64  
7 1     1   473 use IO::Socket::INET;
  1         21148  
  1         7  
8              
9 1     1   443 use vars qw/ @ISA %EXPORT_TAGS @EXPORT_OK $VERSION /;
  1         2  
  1         82  
10              
11             $VERSION = '0.09';
12              
13             # used for route searches
14 1     1   8 use constant EXACT_MATCH => 'o';
  1         1  
  1         145  
15 1     1   7 use constant ONE_LEVEL => 'l';
  1         2  
  1         54  
16 1     1   7 use constant LESS_SPECIFIC => 'L';
  1         3  
  1         45  
17 1     1   5 use constant MORE_SPECIFIC => 'M';
  1         2  
  1         1743  
18              
19             require Exporter;
20             @ISA = qw(Exporter);
21             @EXPORT_OK = qw( EXACT_MATCH ONE_LEVEL LESS_SPECIFIC MORE_SPECIFIC );
22             %EXPORT_TAGS = (
23             'all' => \@EXPORT_OK,
24             'route' => \@EXPORT_OK,
25             );
26              
27             # constructor
28             sub connect {
29 1     1 1 644 my ($class, %args) = @_;
30 1   33     9 my $self = bless {}, ref($class) || $class;
31 1   50     7 $self->{host} = $args{host} || '127.0.0.1';
32 1   50     6 $self->{port} = $args{port} || 43;
33             $self->{tcp} = IO::Socket::INET->new(
34             PeerAddr => $self->{host},
35             PeerPort => $self->{port},
36 1         9 Proto => 'tcp'
37             );
38              
39 1 50       243816 unless ($self->{tcp}) {
40 0         0 $self->{errstr} = "cannot create socket: $@";
41 0         0 return;
42             }
43              
44 1 50       27 return undef if $self->error();
45 1         23 $self->_multi_mode();
46 1         8 $self->_identify();
47 1         9 return $self;
48             }
49              
50             sub get_routes_by_origin {
51 1     1 1 4 my ($self, $as) = @_;
52 1 50       5 croak 'usage: $whois->get_routes_by_origin( $as_number )'
53             unless @_ == 2;
54 1 50       7 $as = 'as'.$as unless $as =~ /^as/i;
55 1         9 $self->{tcp}->send("!g${as}\n");
56 1 50       138 if (my $data = $self->_response()) {
57 1 50       163 return wantarray ? split(" ", $data) : $data;
58             }
59 0         0 return ();
60             }
61              
62             # RIPE-181 Only
63             sub get_routes_by_community {
64 0     0 1 0 my ($self, $community) = @_;
65 0 0       0 croak 'usage: $whois->get_routes_by_community( $community )'
66             unless @_ == 2;
67 0         0 $self->{tcp}->send("!h${community}\n");
68 0 0       0 if (my $data = $self->_response()) {
69 0 0       0 return wantarray ? split(" ", $data) : $data;
70             }
71 0         0 return ();
72             }
73              
74             sub get_ipv6_routes_by_origin {
75 0     0 1 0 my ($self, $as) = @_;
76 0 0       0 croak 'usage: $whois->get_ipv6_routes_by_origin( $as_number )'
77             unless @_ == 2;
78 0 0       0 $as = 'as'.$as unless $as =~ /^as/i;
79 0         0 $self->{tcp}->send("!6${as}\n");
80 0 0       0 if (my $data = $self->_response()) {
81 0 0       0 return wantarray ? split(" ", $data) : $data;
82             }
83 0         0 return ();
84             }
85              
86             sub get_sync_info {
87 1     1 1 3 my ($self, @dbs) = @_;
88 1 50       5 my $dbs = (@dbs) ? join(",",@dbs) : '-*';
89 1         11 $self->{tcp}->send("!j${dbs}\n");
90 1         188 return $self->_response();
91             }
92              
93             sub get_as_set {
94 1     1 1 1209 my ($self, $as_set, $expand) = @_;
95 1 50 33     11 croak 'usage: $whois->get_as_set( $as_set )'
96             unless @_ >= 2 && @_ <= 3;
97 1 50       5 $expand = ($expand) ? ',1' : '';
98 1         10 $self->{tcp}->send("!i${as_set}${expand}\n");
99 1 50       139 if (my $data = $self->_response()) {
100 1 50       94 return wantarray ? split(" ", $data) : $data;
101             }
102 0         0 return ();
103             }
104              
105 1     1 1 908 sub get_route_set { my ($self, $route_set, $expand) = @_;
106 1 50 33     12 croak 'usage: $whois->get_route_set( $route_set )'
107             unless @_ >= 2 && @_ <= 3;
108 1 50       5 $expand = ($expand) ? ',1' : '';
109 1         10 $self->{tcp}->send("!i${route_set}${expand}\n");
110 1 50       124 if (my $data = $self->_response()) {
111 1 50       93 return wantarray ? split(" ", $data) : $data;
112             }
113 0         0 return ();
114             }
115              
116             sub match {
117 1     1 1 887 my ($self, $type, $key) = @_;
118 1 50       6 croak 'usage: $whois->match( $object_type, $key )'
119             unless @_ == 3;
120 1         11 $self->{tcp}->send("!m${type},${key}\n");
121 1         127 return $self->_response();
122             }
123              
124             *disconnect = \&quit;
125             sub quit {
126 1     1 1 1307 my $self = shift;
127 1         9 $self->{tcp}->send("!q\n");
128             }
129              
130             sub _identify {
131 1     1   2 my ($self) = @_;
132 1         6 $self->{tcp}->send("!nNet::IRR\n");
133 1         55 return $self->_response();
134             }
135              
136             sub _multi_mode {
137 1     1   5 my ($self) = @_;
138 1         25 $self->{tcp}->send("!!\n");
139 1         328 return 1;
140             }
141              
142             sub get_irrd_version {
143 1     1 1 937 my ($self) = @_;
144 1         10 $self->{tcp}->send("!v\n");
145 1         184 return $self->_response();
146             }
147              
148             sub route_search {
149 2     2 1 1670 my ($self, $route, $specific) = @_;
150 2 50 33     24 croak 'usage: $whois->route_search( $route )'
151             unless @_ >= 2 && @_ <= 3;
152 2 50       12 $specific = ($specific) ? ",$specific" : '';
153 2         20 $self->{tcp}->send("!r${route}${specific}\n");
154 2         406 my $response = $self->_response();
155 2 100       14 chomp($response) if $response;
156 2 100       17 $response =~ s/\s*$// if $response;
157 2         37 return $response;
158             }
159              
160             sub sources {
161 0     0 1 0 my ($self, @sources) = @_;
162 0 0       0 my $source = (@sources) ? join(",", @sources) : '-lc';
163 0         0 $self->{tcp}->send("!s${source}\n");
164 0         0 my $response = $self->_response();
165 0 0       0 chomp($response) if $response;
166 0 0       0 return wantarray ? split(',', $response) : $response;
167             }
168              
169             sub update {
170 0     0 1 0 my ($self, $db, $action, $object) = @_;
171 0 0       0 croak 'usage: $whois->update( $db, "ADD|DEL", $object )'
172             unless @_ == 4;
173 0 0 0     0 croak 'second argument to $whois->update() must be either ADD or DEL'
174             unless $action eq 'ADD' || $action eq 'DEL';
175 0         0 $self->{tcp}->send( sprintf("!us%s\n%s\n\n%s\n\n!ue\n", $db, $action, $object) );
176 0         0 return $self->_response();
177             }
178              
179             sub _response {
180 9     9   29 my $self = shift;
181 9         23 my $t = $self->{tcp};
182 9         348 my $header = $t->getline();
183 9         1131172 my $error_prefix = 'Net::IRR read error';
184 9 50       78 if (not defined $header) {
185 0         0 $self->{errstr} = sprintf("%s: no data read from %s:%d\n", $error_prefix, $self->{host}, $self->{port});
186 0         0 return ();
187             }
188 9 100       103 return () if ($header =~ /^[CDEF].*$/);
189 7         109 my($data_length) = $header =~ /^A(.*)$/;
190 7         25 my $data = '';
191 7         66 while($data_length != length($data)) {
192 380         17185 $data .= $t->getline();
193             }
194             carp sprintf("%s: only received %d out of %d bytes from %s:%d\n", $error_prefix, length($data), $data_length, $self->{host}, $self->{port})
195 7 50       298 if $data_length != length($data);
196 7         175 my $footer = $t->getline();
197 7         292 return $data;
198             }
199              
200             sub error {
201 2     2 1 14 my $self = shift;
202 2         14 return $self->{errstr};
203             }
204              
205             1;
206             __END__