File Coverage

blib/lib/Farly/Opts/Search.pm
Criterion Covered Total %
statement 104 117 88.8
branch 29 54 53.7
condition n/a
subroutine 24 24 100.0
pod 3 3 100.0
total 160 198 80.8


line stmt bran cond sub pod time code
1             package Farly::Opts::Search;
2            
3 1     1   507 use 5.008008;
  1         4  
  1         28  
4 1     1   4 use strict;
  1         2  
  1         38  
5 1     1   5 use warnings;
  1         1  
  1         21  
6 1     1   16 use Carp;
  1         1  
  1         56  
7 1     1   905 use Socket;
  1         5139  
  1         570  
8 1     1   8 use Log::Any qw($log);
  1         3  
  1         8  
9 1     1   554 use Farly::ASA::PortFormatter;
  1         2  
  1         25  
10 1     1   500 use Farly::ASA::ProtocolFormatter;
  1         2  
  1         1702  
11            
12             our $VERSION = '0.26';
13            
14             sub new {
15 6     6 1 556 my ( $class, $opts ) = @_;
16            
17 6 50       14 defined($opts)
18             or confess "options hash object required";
19            
20 6 50       17 confess "invalid options type ", ref($opts)
21             unless ( ref($opts) eq 'HASH' );
22            
23 6         23 my $self = {
24             SEARCH => Farly::Object->new(),
25             FILTER => Farly::Object::List->new(),
26             };
27            
28 6         131 bless( $self, $class );
29            
30 6         43 $log->info("$self new");
31            
32 6         24 $self->_check_opts($opts);
33            
34 4         50 return $self;
35             }
36            
37 40     40 1 197 sub search { return $_[0]->{SEARCH} }
38 10     10 1 82 sub filter { return $_[0]->{FILTER} }
39            
40             sub _check_opts {
41 6     6   8 my ( $self, $opts ) = @_;
42            
43 6         16 $self->_id($opts);
44 6         15 $self->_action($opts);
45 6         15 $self->_protocol($opts);
46 6         15 $self->_src_ip($opts);
47 5         17 $self->_dst_ip($opts);
48 5         16 $self->_src_port($opts);
49 5         13 $self->_dst_port($opts);
50 5         19 $self->_exclude_src($opts);
51 4         64 $self->_exclude_dst($opts);
52            
53             }
54            
55             sub _id {
56 6     6   8 my ( $self, $opts ) = @_;
57            
58 6 50       18 if ( defined $opts->{'id'} ) {
59 6         13 $self->search->set( 'ID', Farly::Value::String->new( $opts->{'id'} ) );
60             }
61             }
62            
63             sub _action {
64 6     6   7 my ( $self, $opts ) = @_;
65            
66 6 50       14 if ( defined $opts->{'action'} ) {
67 6         8 my $action = $opts->{'action'};
68 6 50       35 if ( $action !~ /permit|deny/ ) {
69 0         0 die "action must be 'permit' or 'deny'";
70             }
71 6         9 $self->search->set( 'ACTION', Farly::Value::String->new($action) );
72             }
73             }
74            
75             sub _protocol {
76 6     6   8 my ( $self, $opts ) = @_;
77            
78 6 50       21 if ( defined $opts->{'p'} ) {
79 6         10 my $protocol = $opts->{'p'};
80 6         15 $protocol =~ s/^\s+|\s+$//g;
81 6         32 my $protocol_formatter = Farly::ASA::ProtocolFormatter->new();
82 6 50       38 if ( $protocol =~ /^\d+$/ ) {
    50          
83 0         0 $self->search->set( 'PROTOCOL', Farly::Transport::Protocol->new($protocol) );
84             }
85             elsif ( $protocol =~ /^\S+$/ ) {
86 6         17 my $protocol_number = $protocol_formatter->as_integer($protocol);
87 6 50       13 die "unknown protocol '$protocol'\n"
88             if ( !defined $protocol_number );
89 6         10 $self->search->set( 'PROTOCOL', Farly::Transport::Protocol->new($protocol_number) );
90             }
91            
92             }
93             }
94            
95             sub _set_ip {
96 11     11   15 my ( $self, $property, $ip ) = @_;
97            
98 11 50       70 if ( $ip =~ /((\d{1,3})((\.)(\d{1,3})){3})\s+((\d{1,3})((\.)(\d{1,3})){3})/ )
    100          
    100          
    50          
99             {
100 0         0 $self->search->set( $property, Farly::IPv4::Network->new($ip) );
101             }
102             elsif ( $ip =~ /(\d{1,3}(\.\d{1,3}){3})(\/)(\d+)/ ) {
103 8         16 $self->search->set( $property, Farly::IPv4::Network->new($ip) );
104             }
105             elsif ( $ip =~ /((\d{1,3})((\.)(\d{1,3})){3})/ ) {
106 2         5 $self->search->set( $property, Farly::IPv4::Address->new($ip) );
107             }
108             elsif ( $ip =~ /\S+/ ) {
109 0         0 my @addresses = gethostbyname($ip);
110 0 0       0 if (@addresses) {
111 0         0 @addresses = map { inet_ntoa($_) } @addresses[ 4 .. $#addresses ];
  0         0  
112 0         0 $self->search->set( $property, Farly::IPv4::Address->new( $addresses[0] ) );
113 0         0 print "$ip [", $addresses[0], "]\n";
114             }
115             else {
116 0         0 die "Unable to resolve host '$ip'\n";
117             }
118             }
119             else {
120 1         7 die "Invalid IP '$ip'\n";
121             }
122             }
123            
124             sub _src_ip {
125 6     6   8 my ( $self, $opts ) = @_;
126            
127 6 50       16 if ( defined $opts->{'s'} ) {
128 6         8 my $ip = $opts->{'s'};
129 6         13 $self->_set_ip( 'SRC_IP', $ip );
130             }
131             }
132            
133             sub _dst_ip {
134 5     5   6 my ( $self, $opts ) = @_;
135            
136 5 50       15 if ( defined $opts->{'d'} ) {
137 5         7 my $ip = $opts->{'d'};
138 5         10 $self->_set_ip( 'DST_IP', $ip );
139             }
140             }
141            
142             sub _set_port {
143 10     10   13 my ( $self, $property, $port ) = @_;
144            
145 10         37 my $port_formatter = Farly::ASA::PortFormatter->new();
146            
147 10         35 $port =~ s/^\s+|\s+$//g;
148            
149 10 50       26 if ( $port =~ /^\d+$/ ) {
    0          
150 10         20 $self->search->set( $property, Farly::Transport::Port->new($port) );
151             }
152             elsif ( $port =~ /^\S+$/ ) {
153 0 0       0 my $port_number = $port_formatter->as_integer($port)
154             or die "unknown port '$port'\n";
155 0         0 $self->search->set( $property, Farly::Transport::Port->new($port_number) );
156             }
157             else {
158 0         0 die "$port is not a port number\n";
159             }
160             }
161            
162             sub _src_port {
163 5     5   8 my ( $self, $opts ) = @_;
164            
165 5 50       13 if ( defined $opts->{'sport'} ) {
166 5         6 my $port = $opts->{'sport'};
167 5         10 $self->_set_port( 'SRC_PORT', $port );
168             }
169             }
170            
171             sub _dst_port {
172 5     5   7 my ( $self, $opts ) = @_;
173            
174 5 50       11 if ( defined $opts->{'dport'} ) {
175 5         6 my $port = $opts->{'dport'};
176 5         9 $self->_set_port( 'DST_PORT', $port );
177             }
178             }
179            
180             sub _set_exclude {
181 2     2   167 my ( $self, $property, $file_name ) = @_;
182            
183 2 50       19 my $file = IO::File->new($file_name)
184             or croak "Please specify a valid file for exclusion\n";
185            
186 2         277 while ( my $line = $file->getline() ) {
187 4 50       152 next if ( $line !~ /\S+/ );
188 4         16 my $exlude = Farly::Object->new();
189 4         18 $exlude->set( $property, Farly::IPv4::Network->new($line) );
190 4         11 $self->filter->add($exlude);
191             }
192            
193             }
194            
195             sub _exclude_src {
196 5     5   8 my ( $self, $opts ) = @_;
197            
198 5 100       14 if ( defined $opts->{'exclude-src'} ) {
199 2         4 my $file_name = $opts->{'exclude-src'};
200 2 100       266 croak "$file_name is not a valid file" unless ( -f $file_name );
201 1         4 $self->_set_exclude( 'SRC_IP', $file_name );
202             }
203             }
204            
205             sub _exclude_dst {
206 4     4   5 my ( $self, $opts ) = @_;
207            
208 4 100       11 if ( defined $opts->{'exclude-dst'} ) {
209 1         2 my $file_name = $opts->{'exclude-dst'};
210 1 50       46 croak "$file_name is not a valid file" unless ( -f $file_name );
211 1         11 $self->_set_exclude( 'DST_IP', $file_name );
212             }
213             }
214            
215             1;
216             __END__