Compare commits

...

19 Commits

Author SHA1 Message Date
Zane C. B-H aead20b4a0 not the changes and bump the port version 2019-05-25 01:07:30 -05:00
Zane C. B-H d550f30d45 update t/search.t to match the current behaviour of Net::CIDR 2019-05-25 01:04:08 -05:00
Zane C. B-H 4052319faa bump to 0.2.1 and note changes 2019-04-15 21:17:52 -05:00
Zane C. B-H 8941c256ac add a missing depend of Net::DNS 2019-04-15 21:15:19 -05:00
Zane C. B-H d4cbe61492 Merge branch 'master' of https://gitea.eesdp.org/vvelox/Parse-Netstat-Search 2019-04-15 02:34:57 -05:00
Zane C. B-H 906f113bef hmm... should release 0.2.0 2019-04-15 02:33:54 -05:00
Zane C. B-H 8a48932f14 invert stuff all works now and is documented 2019-02-28 10:36:20 -06:00
Zane C. B-H d78c077ccd invert stuff all works now and is documented 2019-02-28 10:32:47 -06:00
Zane C. B-H fde8327c9a add in the ability to inversion, PTR, and regexp PTR... invertsion related methods need completed 2019-02-28 10:01:17 -06:00
Zane C. B-H 13184cf0d5 ptr and regexp ptr searching now works 2019-02-28 09:38:55 -06:00
Zane C. B-H 5fb4f34090 correct a small typo and begin working on PTR stuff 2019-02-28 05:36:09 -06:00
Zane C. B-H 6112ee058d bump version, document changes, add a text to test for any future regressions 2019-02-26 03:57:46 -06:00
Zane C. B-H 7c479576bf ...yay! Net::CIDR does not like when both IPv4 and IPv6 are combined 2019-02-26 03:47:54 -06:00
Zane C. B-H 359daebdd5 bump to 0.1.0 and note the changes 2019-02-26 00:12:25 -06:00
Zane C. B-H 1674f4f45a document *_pp 2019-02-26 00:06:15 -06:00
Zane C. B-H edaaadd874 add explicit tests for new IPv6 stuff 2019-02-25 23:54:55 -06:00
Zane C. B-H 60bb179e74 test data now includes a funny IPv6 to test to make sure handling of
slightly misformed data returned from Parse::Netstat is handled
2019-02-25 23:42:21 -06:00
Zane C. B-H bcf609fba4 fix a few issues where it does not like how IPv6 stuff is sometimes reported by netstat 2019-02-25 23:34:39 -06:00
Zane C. B-H b3bbb47024 bump to 0.0.3 to fix an issue where Net::CIDR does sometimes not like some IPs 2019-02-25 06:27:23 -06:00
4 changed files with 703 additions and 56 deletions

View File

@ -1,15 +1,44 @@
Revision history for Parse-Netstat-Search
0.0.2 2019-02-24/08:30
- Previous issue turned out to be specifically. Added
addtional handling for UDP as it is stateless. This
removes '?' from previously. State for for UDP is ''.
0.2.2 2019-05-23/01:10
- Net::CIDR now treats ::/0 and 0.0.0.0/0 as the same.
t/search.t has been updated to reflect this.
0.0.1 2019-02-24/06:30
- Handle where FreeBSD does not state LISTEN.
- Add a missing error flag.
- If state is not defined use '?'.
0.2.1 2019-04-15/21:20
- Add missing depend Net::DNS. (SREZIC, #129196)
0.0.0 2019-02-20/06:00
-Initial release.
0.2.0 2019-04-15/02:30
- Minor typo correction(japh).
- Add PTR search support.
- Add regexp PTR search support.
0.1.1 2019-02-26/04:00
- Apparently Net::CIDR does not like searching IPv4 and IPv6 at the
same time. Each requested CIDR is now checked on its own. While
it says the functions will handle both in the docs, apparently
this does not mean at the same time.
0.1.0 2019-02-26/00:15
- Add in handling of % in IPv6 addresses.
- Add in handling of slightly malformed IPv6 address that netstat
on FreeBSD seems to sometimes produce, using ':.' for the port
delimiter instead of '.'. This is not to be confused with ::
appearing at the end, but like "fe80::4ecc:6aff:.123".
0.0.3 2019-02-25/06:30
- Use eval to talk to Net::CIDR as it seems to not always like IPv6.
This allows it to continue instead of killing the entire op.
0.0.2 2019-02-24/08:30
- Previous issue turned out to be specifically. Added
addtional handling for UDP as it is stateless. This
removes '?' from previously. State for for UDP is ''.
0.0.1 2019-02-24/06:30
- Handle where FreeBSD does not state LISTEN.
- Add a missing error flag.
- If state is not defined use '?'.
0.0.0 2019-02-20/06:00
-Initial release.

View File

@ -19,6 +19,7 @@ WriteMakefile(
'Net::CIDR' => '0',
'Parse::Netstat'=>'0.14',
'Error::Helper' => '1.0.0',
'Net::DNS' => '1.20',
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Parse-Netstat-Search-*' },

View File

@ -5,6 +5,7 @@ use strict;
use warnings;
use base 'Error::Helper';
use Net::CIDR;
use Net::DNS;
=head1 NAME
@ -12,11 +13,11 @@ Parse::Netstat::Search - Searches the connection list in the results returned by
=head1 VERSION
Version 0.0.2
Version 0.2.2
=cut
our $VERSION = '0.0.2';
our $VERSION = '0.2.2';
=head1 SYNOPSIS
@ -25,7 +26,7 @@ our $VERSION = '0.0.2';
use Parse::Netstat::Search;
use Parse::Netstat qw(parse_netstat);
my $res = parse_netstat(output => join("", `netstat -anp`), flavor=>'linux');
my $res = parse_netstat(output => join("", `netstat -n`), flavor=>$^O);
my $search = Parse::Netstat::Search->new();
@ -37,6 +38,37 @@ our $VERSION = '0.0.2';
Two big things to bet aware of is this module does not currently resulve names and this module
does not handle unix sockets. Unix sockets will just be skipped over.
The connection hashes returned differ from Parse::Netstat slightly. Below is what a standard ones
for IPv4/6 looks like.
{
'foreign_host'=>'10.0.0.1',
'local_host'=>'10.0.0.2',
'foreign_port'=>'22222',
'local_port'=>'22',
'sendq'=>'0',
'recvq'=>'0',
'state' => 'ESTABLISHED',
'proto' => 'tcp4',
}
This module has two additional keys, "local_pp" and "foreign_pp". Which contains and data
after % in a address. So "fe80::1%lo0" would be split into "fe80::1" and "lo0" as in the
example below.
{
'state' => '',
'foreign_host' => '*',
'local_port' => '123',
'proto' => 'udp6',
'foreign_pp' => undef,
'foreign_port' => '*',
'local_host' => 'fe80::1',
'recvq' => '44',
'local_pp' => 'lo0',
'sendq' => '33'
}
=head1 methods
=head2 new
@ -63,6 +95,15 @@ sub new{
protocols=>{},
ports=>{},
states=>{},
ptrs=>{},
ptrs_r=>[],
resolver=>Net::DNS::Resolver->new,
ptr_invert=>0,
ptr_r_invert=>0,
cidr_invert=>0,
protocol_invert=>0,
state_invert=>0,
port_invert=>0,
};
bless $self;
@ -90,6 +131,28 @@ sub get_cidrs{
return @{ $self->{cidrs} };
}
=head2 get_cidrs_invert
Gets the invert status of the CIDRs search.
if ( $search->get_cidrs_invert ){
print "The search will be inverted\n";
}else{
print "The search will not be inverted";
}
=cut
sub get_cidrs_invert{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return $self->{cidr_invert};
}
=head2 get_ports
Gets a list of desired ports.
@ -111,6 +174,28 @@ sub get_ports{
return keys( %{ $self->{ports} } );
}
=head2 get_ports_invert
Gets the invert status of the ports search.
if ( $search->get_ports_invert ){
print "The search will be inverted\n";
}else{
print "The search will not be inverted";
}
=cut
sub get_ports_invert{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return $self->{port_invert};
}
=head2 get_protocols
Gets a list of desired protocols.
@ -135,6 +220,28 @@ sub get_protocols{
return keys( %{ $self->{protocols} } );
}
=head2 get_protocols_invert
Gets the invert status of the protocols search.
if ( $search->get_protocols_invert ){
print "The search will be inverted\n";
}else{
print "The search will not be inverted";
}
=cut
sub get_protocols_invert{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return $self->{protocol_invert};
}
=head2 get_states
Get a list of desired sets.
@ -158,6 +265,112 @@ sub get_states{
return keys( %{ $self->{states} } );
}
=head2 get_state_invert
Gets the invert status of the states search.
if ( $search->get_state_invert ){
print "The search will be inverted\n";
}else{
print "The search will not be inverted";
}
=cut
sub get_states_invert{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return $self->{state_invert};
}
=head2 get_ptrs
Gets the list of PTRs to search for.
The returned value is a array. Each item is a PTR.
my @PTRs=$search->get_ptrs;
=cut
sub get_ptrs{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return keys( %{ $self->{ptrs} } );
}
=head2 get_ptrs_invert
Gets the invert status of the PTRs search.
if ( $search->get_ptr_invert ){
print "The search will be inverted\n";
}else{
print "The search will not be inverted";
}
=cut
sub get_ptrs_invert{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return $self->{ptr_invert};
}
=head2 get_ptrs_r
Gets the list of PTR regexps to search for.
The returned value is a array. Each item is a PTR.
my @regexps=$search->get_ptrs_r;
=cut
sub get_ptrs_r{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return @{ $self->{ptrs_r} };
}
=head2 get_ptrs_invert
Gets the invert status of the PTRs search.
if ( $search->get_ptr_invert ){
print "The search will be inverted\n";
}else{
print "The search will not be inverted";
}
=cut
sub get_ptrs_r_invert{
my $self=$_[0];
if( ! $self->errorblank ){
return undef;
}
return $self->{ptr_r_invert};
}
=head2 search
This runs the search results.
@ -181,7 +394,7 @@ sub search{
( ! 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->{errorString}='$res->[2]->{active_conns} not defined. Does not appear to be a Parse::Netstat return';
$self->warn;
return undef;
}
@ -194,6 +407,8 @@ sub search{
my $cidr_require=0;
my $protocol_require=0;
my $state_require=0;
my $ptr_require=0;
my $ptr_r_require=0;
# figure out what we need to check for
if (defined( $self->{cidrs}[0] )){
@ -208,6 +423,12 @@ sub search{
if (defined( (keys(%{ $self->{states} }))[0] )){
$state_require=1;
}
if (defined( (keys(%{ $self->{ptrs} }))[0] )){
$ptr_require=1;
}
if (defined( $self->{ptrs_r}[0] )){
$ptr_r_require=1;
}
my $res_int=0;
while ( defined( $res->[2]->{active_conns}->[$res_int] ) ){
@ -219,11 +440,24 @@ sub search{
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};
#my $local_host=$res->[2]->{active_conns}->[$res_int]->{local_host};
#my $foreign_host=$res->[2]->{active_conns}->[$res_int]->{foreign_host};
my $sendq=$res->[2]->{active_conns}->[$res_int]->{sendq};
my $recvq=$res->[2]->{active_conns}->[$res_int]->{recvq};
#handle IPv6 % stuff if needed
my ( $local_host, $local_pp ) = split( /\%/, $res->[2]->{active_conns}->[$res_int]->{local_host} );
my ( $foreign_host, $foreign_pp ) = split( /\%/, $res->[2]->{active_conns}->[$res_int]->{foreign_host} );
# Handle when parse netstat chokes on lines like...
# udp6 0 0 fe80::4ecc:6aff:.123 *.*
if ( $local_host =~ /[0123456789AaBbCcDdEeFf]\:$/ ){
$local_host =~ s/\:$//;
}
if ( $foreign_host =~ /[0123456789AaBbCcDdEeFf]\:$/ ){
$foreign_host =~ s/\:$//;
}
# UDP is stateless and in some cases on listening ports for it Parse::Netstat
# does not return any host, so use * for it.
if (!defined( $foreign_host )){
@ -247,39 +481,44 @@ sub search{
my $port_meet=1;
my $cidr_meet=1;
my $protocol_meet=1;
my $ptr_meet=1;
my $ptr_r_meet=1;
my $protocol_search=lc( $protocol );
my $state_meet=1;
my $state_search=lc( $state );
# 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;
}
# XOR the meet and require, setting the meet to false if required
$port_meet = $port_meet ^ $port_require;
$cidr_meet = $cidr_meet ^ $cidr_require;
$protocol_meet = $protocol_meet ^ $protocol_require;
$state_meet = $state_meet ^ $state_require;
$ptr_meet = $ptr_meet ^ $ptr_require;
$ptr_r_meet = $ptr_r_meet ^ $ptr_r_require;
# checks the forient port against each CIDR
if (
$cidr_require &&
(
(
( $foreign_host ne '*' ) &&
( Net::CIDR::cidrlookup( $foreign_host, @{ $self->{cidrs} } ) )
) ||
(
( $local_host ne '*' ) &&
( Net::CIDR::cidrlookup( $local_host, @{ $self->{cidrs} } ) )
)
)
) {
$cidr_meet=1;
my @cidrs=@{ $self->{cidrs} };
if ( $cidr_require ){
# check each one by its self... Net::CIDR will error if you tell it to search for in IPv4 and IPv6 space at the same time
my @cidrs=@{ $self->{cidrs} };
my $cidr=pop( @cidrs );
while (
( defined( $cidr ) ) &&
( ! $cidr_meet )
){
if (
(
( $foreign_host ne '*' ) &&
( eval{ Net::CIDR::cidrlookup( $foreign_host, $cidr ) })
) || (
( $local_host ne '*' ) &&
( eval{ Net::CIDR::cidrlookup( $local_host, $cidr ) } )
)
){
$cidr_meet=1;
}
$cidr=pop( @cidrs );
}
}
# handle it if port checking is required
@ -309,9 +548,90 @@ sub search{
$state_meet=1;
}
# check if the PTR of any matches
if ( $ptr_require ){
#look both up
my $answer_f=$self->{resolver}->search( $foreign_host );
my $answer_l=$self->{resolver}->search( $local_host );
# figure out if we have a ptr or not for foriegn host and if so grab it
my $ptr_f='NOTFOUND';
if ( defined( $answer_f->{answer}[0] ) &&
( ref( $answer_f->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
){
$ptr_f=lc($answer_f->{answer}[0]->ptrdname);
}
# figure out if we have a ptr or not for foriegn host and if so grab it
my $ptr_l='NOTFOUND';
if ( defined( $answer_l->{answer}[0] ) &&
( ref( $answer_l->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
){
$ptr_l=lc($answer_l->{answer}[0]->ptrdname);
}
# now that we have it, check if either are defined in the lookup table
if (
defined( $self->{ptrs}{$ptr_l} ) ||
defined( $self->{ptrs}{$ptr_f} )
){
$ptr_meet=1;
}
}
# check if the PTR of any matches
if ( $ptr_r_require ){
#look both up
my $answer_f=$self->{resolver}->search( $foreign_host );
my $answer_l=$self->{resolver}->search( $local_host );
# figure out if we have a ptr or not for foriegn host and if so grab it
my $ptr_f='NOTFOUND';
if ( defined( $answer_f->{answer}[0] ) &&
( ref( $answer_f->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
){
$ptr_f=lc($answer_f->{answer}[0]->ptrdname);
}
# figure out if we have a ptr or not for foriegn host and if so grab it
my $ptr_l='NOTFOUND';
if ( defined( $answer_l->{answer}[0] ) &&
( ref( $answer_l->{answer}[0] ) eq 'Net::DNS::RR::PTR' )
){
$ptr_l=lc($answer_l->{answer}[0]->ptrdname);
}
# check if any of them match
my @ptrs_r=@{ $self->{ptrs_r} };
my $ptr=pop( @ptrs_r );
while (
defined( $ptr ) &&
( ! $ptr_r_meet )
){
if (
( $ptr_f =~ /$ptr/ ) ||
( $ptr_l =~ /$ptr/ )
){
$ptr_r_meet=1;
}
$ptr=pop( @ptrs_r );
}
}
# handle inversion
$port_meet = $port_meet ^ $self->{port_invert};
$protocol_meet = $protocol_meet ^ $self->{protocol_invert};
$cidr_meet = $cidr_meet ^ $self->{cidr_invert};
$state_meet = $state_meet ^ $self->{state_invert};
$ptr_require = $ptr_require ^ $self->{ptr_invert};
$ptr_r_require = $ptr_r_require ^ $self->{ptr_r_invert};
# if these are all good, add them
if (
$port_meet && $protocol_meet && $cidr_meet && $state_meet
$port_meet && $protocol_meet && $cidr_meet && $state_meet &&
$ptr_meet && $ptr_r_meet
){
push( @found, {
'foreign_port'=>$foreign_port,
@ -322,6 +642,8 @@ sub search{
'recvq'=>$recvq,
'proto'=>$protocol,
'state'=>$state,
'local_pp'=>$local_pp,
'foreign_pp'=>$foreign_pp,
}
);
}
@ -393,6 +715,38 @@ sub set_cidrs{
return 1;
}
=head2 set_cidrs_invert
This sets if the CIDRs search should be inverted or not.
One value is taken and that is a boolean.
# if it does not match, hit on it
$search->set_cidrs_invert(1);
# only hit on matches, the default
$search->set_cidrs_invert; # or...
$search->set_cidrs_invert(0);
=cut
sub set_cidrs_invert{
my $self=$_[0];
my $bool=$_[1];
if( ! $self->errorblank ){
return undef;
}
if ( $bool ){
$self->{cidr_invert}=1;
}else{
$self->{cidr_invert}=0;
}
return 1;
}
=head2 set_ports
This sets the ports to search for in either
@ -458,6 +812,38 @@ sub set_ports{
return 1;
}
=head2 set_ports_invert
This sets if the ports search should be inverted or not.
One value is taken and that is a boolean.
# if it does not match, hit on it
$search->set_port_invert(1);
# only hit on matches, the default
$search->set_port_invert; # or...
$search->set_port_invert(0);
=cut
sub set_ports_invert{
my $self=$_[0];
my $bool=$_[1];
if( ! $self->errorblank ){
return undef;
}
if ( $bool ){
$self->{port_invert}=1;
}else{
$self->{port_invert}=0;
}
return 1;
}
=head2 set_protocols
Sets the list of desired protocols to match.
@ -474,9 +860,6 @@ Starting and trailing white space is removed.
# Set the desired ports to the contents of @protocols.
$search->set_protocols( \@protocols );
if ( $search->error ){
warn("Bad value in ports array");
}
# removes any previous selections
$search->set_protocols;
@ -516,6 +899,188 @@ sub set_protocols{
return 1;
}
=head2 set_protocols_invert
This sets if the protocols search should be inverted or not.
One value is taken and that is a boolean.
# if it does not match, hit on it
$search->set_port_invert(1);
# only hit on matches, the default
$search->set_protocol_invert; # or...
$search->set_protocol_invert(0);
=cut
sub set_protocols_invert{
my $self=$_[0];
my $bool=$_[1];
if( ! $self->errorblank ){
return undef;
}
if ( $bool ){
$self->{protocol_invert}=1;
}else{
$self->{protocol_invert}=0;
}
return 1;
}
=head2 set_ptrs
This sets a list of PTRs to search for.
One value is taken and that is a array.
If this is undef, then previous settings will be cleared.
White space, [\ \t], at the start or end of each
item is removed. It is then converted to lowercase
and saved for later lookup.
# Set the desired PTRs to the contents of @ptrs.
$search->set_ptrs( \@ptrs );
# removes any previous selections
$search->set_ptrs;
=cut
sub set_ptrs{
my $self=$_[0];
my @ptrs;
if ( defined( $_[1] ) ){
@ptrs=@{ $_[1] };
}
if( ! $self->errorblank ){
return undef;
}
if ( !defined( $ptrs[0] ) ){
$self->{ptrs}={};
}
# convert each one to a array
my %lookup_hash;
my $ptr=pop( @ptrs );
while( defined( $ptr ) ){
$ptr=~s/^[\ \t]*//;
$ptr=~s/^[\ \t]*//;
#create a LCed version of the ptr name
$lookup_hash{ lc( $ptr) }=1;
$ptr=pop( @ptrs );
}
# save it for later use
$self->{ptrs}=\%lookup_hash;
return 1;
}
=head2 set_ptrs_invert
This sets if the PTRs search should be inverted or not.
One value is taken and that is a boolean.
# if it does not match, hit on it
$search->set_ptrs_invert(1);
# only hit on match, the default
$search->set_ptrs_invert; # or...
$search->set_ptrs_invert(0);
=cut
sub set_ptrs_invert{
my $self=$_[0];
my $bool=$_[1];
if( ! $self->errorblank ){
return undef;
}
if ( $bool ){
$self->{ptr_invert}=1;
}else{
$self->{ptr_invert}=0;
}
return 1;
}
=head2 set_ptrs_r
This sets a list of PTRs to search for via regexp
One value is taken and that is a array.
If this is undef, then previous settings will be cleared.
# Set the desired PTRs regexps to the contents of @ptrs.
$search->set_ptrs_r( \@ptrs );
# removes any previous selections
$search->set_ptrs;
=cut
sub set_ptrs_r{
my $self=$_[0];
my @regexps;
if ( defined( $_[1] ) ){
@regexps=@{ $_[1] };
}
if( ! $self->errorblank ){
return undef;
}
$self->{ptrs_r}=\@regexps;
return 1;
}
=head2 set_ptrs_invert
This sets if the regexp PTRs search should be inverted or not.
One value is taken and that is a boolean.
# if it does not match, hit on it
$search->set_ptrs_r_invert(1);
# only hit on match, the default
$search->set_ptrs_r_invert; # or...
$search->set_ptrs_r_invert(0);
=cut
sub set_ptrs_r_invert{
my $self=$_[0];
my $bool=$_[1];
if( ! $self->errorblank ){
return undef;
}
if ( $bool ){
$self->{ptr_r_invert}=1;
}else{
$self->{ptr_r_invert}=0;
}
return 1;
}
=head2 set_states
Sets the list of desired states to match.
@ -574,6 +1139,38 @@ sub set_states{
return 1;
}
=head2 set_ptrs_invert
This sets if the state search should be inverted or not.
One value is taken and that is a boolean.
# if it does not match, hit on it
$search->set_state_invert(1);
# only hit on match, the default
$search->set_state_invert; # or...
$search->set_state_invert(0);
=cut
sub set_state_invert{
my $self=$_[0];
my $bool=$_[1];
if( ! $self->errorblank ){
return undef;
}
if ( $bool ){
$self->{state_invert}=1;
}else{
$self->{state_invert}=0;
}
return 1;
}
=head1 ERROR CODES / FLAGS
Error handling is provided by L<Error::Helper>.
@ -634,7 +1231,7 @@ L<https://metacpan.org/release/Parse-Netstat-Search>
=item * Code Repo
L<http://gitea.eesdp.org/vvelox/Parse-Netstat-Search>
L<https://gitea.eesdp.org/vvelox/Parse-Netstat-Search>
=back

View File

@ -1,7 +1,6 @@
use strict;
use Test::More;
use Data::Dumper;
BEGIN {
use_ok('Parse::Netstat::Search');
@ -82,6 +81,16 @@ my $res=[ '0', '1',
'refs' => '0',
'nextref' => '0'
},
{
'foreign_host' => '*',
'recvq' => '44',
'local_port' => '123',
'local_host' => 'fe80::1:%lo0',
'foreign_port' => '*',
'state' => '',
'proto' => 'udp6',
'sendq' => '33'
},
],
}
];
@ -101,7 +110,7 @@ my $search=Parse::Netstat::Search->new;
#return all non-unix connections
my @found=$search->search($res);
ok( $#found eq '5', 'search, all') or diag('"'.$#found.'" number of returned connections for a empty search instead of "5"');
ok( $#found eq '6', 'search, all') or diag('"'.$#found.'" number of returned connections for a empty search instead of "6"');
# set a state and make sure returns only those
$search->set_states( ['LISTEN'] );
@ -109,7 +118,7 @@ $search->set_states( ['LISTEN'] );
ok( $#found eq '1', 'search, LISTEN state') or diag('"'.$#found.'" number of returned connections for LISTEN state search instead of "2"');
$search->set_states;
@found=$search->search($res);
ok( $#found eq '5', 'search, state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "5"... failed to reset the states');
ok( $#found eq '6', 'search, state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "6"... failed to reset the states');
# makes sure searching based on CIDR works
# set a state and make sure returns only those
@ -124,7 +133,7 @@ $search->set_cidrs( ['10.0.0.0/24','127.0.0.1/32'] );
ok( $#found eq '4', 'search, CIDR 3') or diag('"'.$#found.'" number of returned connections for CIDR 127.0.0.1/32 10.0.0.0/24 search instead of "4"');
$search->set_cidrs;
@found=$search->search($res);
ok( $#found eq '5', 'search, CIDR reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "5"... failed to reset the CIDRs');
ok( $#found eq '6', 'search, CIDR reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "6"... failed to reset the CIDRs');
#make sure we can match multiple items
$search->set_cidrs( ['127.0.0.0/24'] );
@ -134,7 +143,7 @@ ok( $#found eq '0', 'search, CIDR+state') or diag('"'.$#found.'" number of retur
$search->set_cidrs;
$search->set_states;
@found=$search->search($res);
ok( $#found eq '5', 'search, CIDR+state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "5"... failed to reset the CIDRs and states');
ok( $#found eq '6', 'search, CIDR+state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "6"... failed to reset the CIDRs and states');
#make sure we cans search based on protocols
$search->set_protocols(['udp4']);
@ -149,7 +158,7 @@ ok( $#found eq '0', 'search, Protocol+Listen') or diag('"'.$#found.'" number of
$search->set_states;
$search->set_protocols;
@found=$search->search($res);
ok( $#found eq '5', 'search, protocol+state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "5"... failed to reset the protocols and states');
ok( $#found eq '6', 'search, protocol+state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "6"... failed to reset the protocols and states');
#make sure we can search based on ports
$search->set_ports(['22']);
@ -167,6 +176,17 @@ ok( $#found eq '0', 'search, port+state') or diag('"'.$#found.'" number of retur
$search->set_states;
$search->set_ports;
@found=$search->search($res);
ok( $#found eq '5', 'search, port+state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "5"... failed to reset the ports and states');
ok( $#found eq '6', 'search, port+state reset') or diag('"'.$#found.'" number of returned connections for a empty search instead of "6"... failed to reset the ports and states');
done_testing(20);
# find all IPv6 addresses
$search->set_cidrs( ['fe80::/32'] );
@found=$search->search($res);
ok( $#found eq '0', 'IPv6 CIDR search 1') or diag('"'.$#found.'" number of returned connections for fe80::/32 instead of "0"');
ok( $found[0]->{local_pp} eq 'lo0', 'IPv6 % removal test') or diag('"local_pp" not defined for removed % section of IPv6 address. "lo0" expected');
# test for future regrestions in mixed IPv4/6 CIDR lists
$search->set_cidrs( ['fe80::/32','192.168.0.0/16'] );
@found=$search->search($res);
ok( $#found eq '1', 'Mixed IPv4/6 CIDR search 1') or diag('"'.$#found.'" number of returned connections for fe80::/32,192.168.0.0/16 instead of "1"');
done_testing(23);