File Coverage

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


line stmt bran cond sub pod time code
1             package Net::IRR;
2              
3 1     1   26422 use strict;
  1         1  
  1         36  
4 1     1   6 use warnings;
  1         1  
  1         30  
5              
6 1     1   6 use Carp;
  1         5  
  1         93  
7 1     1   8903 use IO::Socket::INET;
  1         34065  
  1         8  
8              
9 1     1   729 use vars qw/ @ISA %EXPORT_TAGS @EXPORT_OK $VERSION /;
  1         2  
  1         99  
10              
11             $VERSION = '0.08';
12              
13             # used for route searches
14 1     1   7 use constant EXACT_MATCH => 'o';
  1         3  
  1         78  
15 1     1   6 use constant ONE_LEVEL => 'l';
  1         2  
  1         43  
16 1     1   5 use constant LESS_SPECIFIC => 'L';
  1         2  
  1         39  
17 1     1   4 use constant MORE_SPECIFIC => 'M';
  1         2  
  1         1825  
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 526 my ($class, %args) = @_;
30 1   33     12 my $self = bless {}, ref($class) || $class;
31 1   50     12 $self->{host} = $args{host} || '127.0.0.1';
32 1   50     9 $self->{port} = $args{port} || 43;
33 1         14 $self->{tcp} = IO::Socket::INET->new(
34             PeerAddr => $self->{host},
35             PeerPort => $self->{port},
36             Proto => 'tcp'
37             );
38              
39 1 50       110027 unless ($self->{tcp}) {
40 0         0 $self->{errstr} = "cannot create socket: $@";
41 0         0 return;
42             }
43              
44 1 50       7 return undef if $self->error();
45 1         5 $self->_multi_mode();
46 1         6 $self->_identify();
47 1         12 return $self;
48             }
49              
50             sub get_routes_by_origin {
51 1     1 1 34 my ($self, $as) = @_;
52 1 50       6 croak 'usage: $whois->get_routes_by_origin( $as_number )'
53             unless @_ == 2;
54 1 50       6 $as = 'as'.$as unless $as =~ /^as/i;
55 1         11 $self->{tcp}->send("!g${as}\n");
56 1 50       178 if (my $data = $self->_response()) {
57 1 50       72 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 2 my ($self, @dbs) = @_;
88 1 50       6 my $dbs = (@dbs) ? join(",",@dbs) : '-*';
89 1         10 $self->{tcp}->send("!j${dbs}\n");
90 1         183 return $self->_response();
91             }
92              
93             sub get_as_set {
94 1     1 1 1680 my ($self, $as_set, $expand) = @_;
95 1 50 33     12 croak 'usage: $whois->get_as_set( $as_set )'
96             unless @_ >= 2 && @_ <= 3;
97 1 50       4 $expand = ($expand) ? ',1' : '';
98 1         10 $self->{tcp}->send("!i${as_set}${expand}\n");
99 1 50       101 if (my $data = $self->_response()) {
100 1 50       30 return wantarray ? split(" ", $data) : $data;
101             }
102 0         0 return ();
103             }
104              
105 1     1 1 1235 sub get_route_set { my ($self, $route_set, $expand) = @_;
106 1 50 33     11 croak 'usage: $whois->get_route_set( $route_set )'
107             unless @_ >= 2 && @_ <= 3;
108 1 50       4 $expand = ($expand) ? ',1' : '';
109 1         9 $self->{tcp}->send("!i${route_set}${expand}\n");
110 1 50       130 if (my $data = $self->_response()) {
111 1 50       76 return wantarray ? split(" ", $data) : $data;
112             }
113 0         0 return ();
114             }
115              
116             sub match {
117 1     1 1 3601 my ($self, $type, $key) = @_;
118 1 50       7 croak 'usage: $whois->match( $object_type, $key )'
119             unless @_ == 3;
120 1         11 $self->{tcp}->send("!m${type},${key}\n");
121 1         1257 return $self->_response();
122             }
123              
124             *disconnect = \&quit;
125             sub quit {
126 1     1 1 857 my $self = shift;
127 1         10 $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         63 return $self->_response();
134             }
135              
136             sub _multi_mode {
137 1     1   3 my ($self) = @_;
138 1         17 $self->{tcp}->send("!!\n");
139 1         413 return 1;
140             }
141              
142             sub get_irrd_version {
143 1     1 1 1740 my ($self) = @_;
144 1         13 $self->{tcp}->send("!v\n");
145 1         345 return $self->_response();
146             }
147              
148             sub route_search {
149 2     2 1 6704 my ($self, $route, $specific) = @_;
150 2 50 33     28 croak 'usage: $whois->route_search( $route )'
151             unless @_ >= 2 && @_ <= 3;
152 2 50       14 $specific = ($specific) ? ",$specific" : '';
153 2         23 $self->{tcp}->send("!r${route}${specific}\n");
154 2         428 my $response = $self->_response();
155 2 50       11 chomp($response) if $response;
156 2 50       57 $response =~ s/\s*$// if $response;
157 2         11 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   25 my $self = shift;
181 9         28 my $t = $self->{tcp};
182 9         432 my $header = $t->getline();
183 9         1083978 my $error_prefix = 'Net::IRR read error';
184 9 50       72 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       311 return () if ($header =~ /^[CDEF].*$/);
189 8         79 my($data_length) = $header =~ /^A(.*)$/;
190 8         21 my $data = '';
191 8         51 while($data_length != length($data)) {
192 391         150187 $data .= $t->getline();
193             }
194 8 50       876 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             if $data_length != length($data);
196 8         241 my $footer = $t->getline();
197 8         348 return $data;
198             }
199              
200             sub error {
201 2     2 1 9 my $self = shift;
202 2         16 return $self->{errstr};
203             }
204              
205             1;
206             __END__