diff --git a/Parse-Netstat-Search/lib/Parse/Netstat/Search.pm b/Parse-Netstat-Search/lib/Parse/Netstat/Search.pm index e7a87ee..fa04890 100644 --- a/Parse-Netstat-Search/lib/Parse/Netstat/Search.pm +++ b/Parse-Netstat-Search/lib/Parse/Netstat/Search.pm @@ -8,7 +8,7 @@ use Net::CIDR; =head1 NAME -Parse::Netstat::Search - Searches the connection list in the hash returned by Parse::Netstat +Parse::Netstat::Search - Searches the connection list in the results returned by Parse::Netstat =head1 VERSION @@ -132,6 +132,147 @@ sub get_states{ return keys( %{ $self->{states} } ); } +=head2 search + +This runs the search results. + + my @found=$search->search( $res ); + +=cut + +sub search{ + my $self=$_[0]; + my $res=$_[1]; + + if( ! $self->errorblank ){ + return undef; + } + + #make sure what ever we are passed is sane and very likely a return from Parse::Netdata + if ( + ( ref( $res ) ne 'ARRAY' ) || + ( ! defined( $res->[2] ) ) || + ( ! defined( $res->[2]->{active_conns} ) ) + ){ + $self->{error}=3; + $self->{errorString}='$res->[2]->{active_conns} not defiend. Does not appear to be a Parse::Netstat return'; + $self->warn; + return undef; + } + + # holds the found results + my @found; + + # requirements checks, defaulting to not required + my $port_require=0; + my $cidr_require=0; + my $protocol_require=0; + my $state_require=0; + + # figure out what we need to check for + if (defined( $self->{cidrs}[0] )){ + $cidr_require=1; + } + if (defined( (keys(%{ $self->{ports} }))[0] )){ + $port_require=1; + } + if (defined( (keys(%{ $self->{protocols} }))[0] )){ + $protocol_require=1; + } + if (defined( (keys(%{ $self->{states} }))[0] )){ + $protocol_require=1; + } + + my $res_int=0; + while ( defined( $res->[2]->{active_conns}->[$res_int] ) ){ + # ignore unix sockets + if ( $res->[2]->{active_conns}->[$res_int]->{proto} ne 'unix' ){ + my $foreign_port=$res->[2]->{active_conns}->[$res_int]->{foreign_port}; + my $state=$res->[2]->{active_conns}->[$res_int]->{state}; + my $protocol=$res->[2]->{active_conns}->[$res_int]->{proto}; + my $local_port=$res->[2]->{active_conns}->[$res_int]->{local_port}; + my $local_host=$res->[2]->{active_conns}->[$res_int]->{local_host}; + my $foreign_host=$res->[2]->{active_conns}->[$res_int]->{foreign_host}; + + # checks for making sure a check is meet... defaults to 1 + my $port_meet=1; + my $cidr_meet=1; + my $protocol_meet=1; + my $state_meet=1; + + # reset the meet checks + if ( $port_require ) { + $port_meet=0; + } + if ( $cidr_require ) { + $cidr_meet=0; + } + if ( $protocol_require ) { + $protocol_meet=0; + } + if ( $state_require ) { + $state_meet=0; + } + + # checks the forient port against each CIDR + if ( + $cidr_require && + ( + ( Net::CIDR::cidrlookup( $foreign_host, @{ $self->{cidrs} } ) ) || + ( Net::CIDR::cidrlookup( $local_host, @{ $self->{cidrs} } ) ) + ) + ) { + $cidr_meet=1; + } + + # handle it if port checking is required + if ( + $port_require && + ( + ( defined( $self->{ports}{$foreign_port} ) ) || + ( defined( $self->{ports}{$local_port} ) ) + ) + ) { + $port_meet=1; + } + + # check protocol to see if it is one that is required + if ( + $protocol_require && + defined( $self->{protocols}{$protocol} ) + ){ + $protocol_meet=1; + } + + # check state to see if it is one that is required + if ( + $state_require && + defined( $self->{states}{$state} ) + ){ + $state_meet=1; + } + + # if these are all good, add them + if ( + $port_meet && $protocol_meet && $cidr_meet && $state_meet + ){ + push( @found, { + 'foreign_port'=>$foreign_port, + 'foriegn_host'=>$foreign_host, + 'local_port'=>$local_port, + 'local_host'=>$local_host, + } + ); + } + + } + + $res_int++; + } + + return @found; +} + =head2 set_cidrs This sets the list of CIDRs to search for @@ -381,6 +522,10 @@ Validation is done by Net::CIDR::cidrvalidate. Could not look up the port number for the specified service. +=head2 3 / badResults + +The passed array does not appear to be properly formatted. + =head1 AUTHOR Zane C. Bowers-Hadley, C<< >>