Compare commits
51 Commits
Author | SHA1 | Date |
---|---|---|
Zane C. B-H | e519e0d7c7 | |
Zane C. B-H | 0ffb462b0b | |
Zane C. B-H | 55cd2535e3 | |
Zane C. B-H | 438d9b7d78 | |
Zane C. B-H | 9ecc05fe34 | |
Zane C. B-H | 680b4cbe62 | |
Zane C. B-H | f3089ada01 | |
Zane C. B-H | adc7220396 | |
Zane C. B-H | 357d7e4dbe | |
Zane C. B-H | f8d90d9732 | |
Zane C. B-H | ae3b04a789 | |
Zane C. B-H | 529fe02f05 | |
Zane C. B-H | 37b53bf0d1 | |
Zane C. B-H | 84b13dba51 | |
Zane C. B-H | 703cd7c497 | |
Zane C. B-H | 5d7b6abc87 | |
Zane C. B-H | 50c0dd68c9 | |
Zane C. B-H | 85618c1cf0 | |
Zane C. B-H | 3c107240c0 | |
Zane C. B-H | 469676b3b4 | |
Zane C. B-H | 62d6c30622 | |
Zane C. B-H | b53a481038 | |
Zane C. B-H | c7d9ece486 | |
Zane C. B-H | 736c1e71ef | |
Zane C. B-H | 9c33541969 | |
Zane C. B-H | 4371e312ba | |
Zane C. B-H | bb355c9e2b | |
Zane C. B-H | ec3bbe7a08 | |
Zane C. B-H | c468f42c0b | |
Zane C. B-H | 3f3e09cfcf | |
Zane C. B-H | 3418883eb5 | |
Zane C. B-H | da5e7f901b | |
Zane C. B-H | 520c0c7127 | |
Zane C. B-H | 404dcaa301 | |
Zane C. B-H | 7301942aee | |
Zane C. B-H | 10313d3606 | |
Zane C. B-H | 50892dba74 | |
Zane C. B-H | 641af2494c | |
Zane C. B-H | 78ec4ae4b3 | |
Zane C. B-H | 7585863c33 | |
Zane C. B-H | 981f1a36f5 | |
Zane C. B-H | 82716c38d1 | |
Zane C. B-H | 9eca932ba8 | |
Zane C. B-H | 8494c8f951 | |
Zane C. B-H | 8a3b999149 | |
Zane C. B-H | 4528a568a1 | |
Zane C. B-H | 8427bc7cc9 | |
Zane C. B-H | c0b093e8ca | |
Zane C. B-H | 34110738af | |
Zane C. B-H | 42548ae33b | |
Zane C. B-H | 1a8d6c1c68 |
|
@ -1,5 +1,56 @@
|
|||
Revision history for Net-Connection-ncnetstat
|
||||
|
||||
0.8.0 2023-06-01/13:15
|
||||
- Don't try to sort by default now.
|
||||
|
||||
0.7.1 2021-02-19/08:00
|
||||
- Bump the min version of Text::ANSITable required to 0.601. Thanks SREZIC / #134375.
|
||||
- Fix some typos in bin/ncnetstat docs. Thanks RSAVAGE / #134382.
|
||||
|
||||
0.7.0 2021-02-19/06:30
|
||||
- Revert to lsof on FreeBSD given formatting problems with
|
||||
sockstat on FreeBSD with long IPv6 addresses.
|
||||
|
||||
0.6.4 2021-02-17/04:00
|
||||
- Change use if around to play friendly with older versions of Perl.
|
||||
|
||||
0.6.3 2021-02-16/10:30
|
||||
- Fix at runtime module use to actually work now. Thanks Grinnz, Botje!
|
||||
|
||||
0.6.2 2021-02-16/02:30
|
||||
- Remove it accidentally using Net::Conection::lsof always.
|
||||
|
||||
0.6.1 2021-02-08/20:00
|
||||
- Accidentally inverted the OS check for FreeBSD in Makefile.PL.
|
||||
|
||||
0.6.0 2021-02-08/08:00
|
||||
- Now uses sockstat on FreeBSD.
|
||||
- Make --pct, -C, --Cl, and -W XORable via $ENV
|
||||
|
||||
0.5.0 2019-09-03/03:30
|
||||
- Add the arg no_pid_user.
|
||||
|
||||
0.4.2 2019-08-20/02:00
|
||||
- Add a missing column style option.
|
||||
- Depend on Data::Unixish::Apply, #130303.
|
||||
- Clean up column code.
|
||||
|
||||
0.4.1 2019-08-14/05:00
|
||||
- Actually use Net::Connection->proc now.
|
||||
|
||||
0.4.0 2019-08-14/04:30
|
||||
- Convert to Text::ANSITable for line wrapping with --Cl
|
||||
|
||||
0.3.0 2019-08-12/06:00
|
||||
- Add support for wchan, pctmem, and pctcpu.
|
||||
|
||||
0.2.0 2019-08-09/08:30
|
||||
- Add regexp command searching.
|
||||
- Update the POD for ncnetstat.
|
||||
|
||||
0.1.1 2019-08-06/21:30
|
||||
- Foreach Host -> Remote Host
|
||||
|
||||
0.1.0 2019-08-06/05:30
|
||||
- Add RegexPTR support.
|
||||
- Add UID support.
|
||||
|
|
|
@ -7,3 +7,5 @@ t/00-load.t
|
|||
t/manifest.t
|
||||
t/pod-coverage.t
|
||||
t/pod.t
|
||||
bin/ncnetstat
|
||||
bin/.exists
|
||||
|
|
|
@ -4,48 +4,56 @@ use warnings;
|
|||
use ExtUtils::MakeMaker;
|
||||
|
||||
my %WriteMakefileArgs = (
|
||||
NAME => 'Net::Connection::ncnetstat',
|
||||
AUTHOR => q{Zane C. Bowers-Hadley <vvelox@vvelox.net>},
|
||||
VERSION_FROM => 'lib/Net/Connection/ncnetstat.pm',
|
||||
ABSTRACT_FROM => 'lib/Net/Connection/ncnetstat.pm',
|
||||
LICENSE => 'artistic_2',
|
||||
MIN_PERL_VERSION => '5.006',
|
||||
INST_SCRIPT => 'bin',
|
||||
CONFIGURE_REQUIRES => {
|
||||
'ExtUtils::MakeMaker' => '0',
|
||||
},
|
||||
TEST_REQUIRES => {
|
||||
'Test::More' => '0',
|
||||
},
|
||||
PREREQ_PM => {
|
||||
'Net::Connection'=>'0.1.0',
|
||||
'Net::Connection::lsof'=>'0.0.2',
|
||||
'Net::Connection::Match'=>'0.2.0',
|
||||
'Net::Connection::Sort'=>'0.0.0',
|
||||
'Term::ANSIColor'=>'4.06',
|
||||
'Text::Table'=>'1.133',
|
||||
'Getopt::Long'=>'0.0.0',
|
||||
},
|
||||
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
|
||||
clean => { FILES => 'Net-Connection-ncnetstat-*' },
|
||||
);
|
||||
NAME => 'Net::Connection::ncnetstat',
|
||||
AUTHOR => q{Zane C. Bowers-Hadley <vvelox@vvelox.net>},
|
||||
VERSION_FROM => 'lib/Net/Connection/ncnetstat.pm',
|
||||
ABSTRACT_FROM => 'lib/Net/Connection/ncnetstat.pm',
|
||||
LICENSE => 'artistic_2',
|
||||
MIN_PERL_VERSION => '5.006',
|
||||
INST_SCRIPT => 'bin',
|
||||
CONFIGURE_REQUIRES => {
|
||||
'ExtUtils::MakeMaker' => '0',
|
||||
},
|
||||
TEST_REQUIRES => {
|
||||
'Test::More' => '0',
|
||||
},
|
||||
PREREQ_PM => {
|
||||
'Net::Connection' => '0.2.0',
|
||||
'Net::Connection::lsof' => '0.3.0',
|
||||
'Net::Connection::Match' => '0.5.0',
|
||||
'Net::Connection::Sort' => '0.1.1',
|
||||
'Term::ANSIColor' => '4.06',
|
||||
'Text::ANSITable' => '0.601',
|
||||
'Getopt::Long' => '0.0.0',
|
||||
'Data::Unixish::Apply' => '1.570',
|
||||
},
|
||||
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
|
||||
clean => { FILES => 'Net-Connection-ncnetstat-*' },
|
||||
);
|
||||
|
||||
#if ( $^O =~ /freebsd/ ) {
|
||||
# $WriteMakefileArgs{PREREQ_PM}{'Net::Connection::FreeBSD_sockstat'} = '0.0.1';
|
||||
#}
|
||||
#else {
|
||||
$WriteMakefileArgs{PREREQ_PM}{'Net::Connection::lsof'} = '0.2.0';
|
||||
#}
|
||||
|
||||
# Compatibility with old versions of ExtUtils::MakeMaker
|
||||
unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) {
|
||||
my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
|
||||
@{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires;
|
||||
unless ( eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 } ) {
|
||||
my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
|
||||
@{ $WriteMakefileArgs{PREREQ_PM} }{ keys %$test_requires } = values %$test_requires;
|
||||
}
|
||||
|
||||
unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) {
|
||||
my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
|
||||
@{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires;
|
||||
unless ( eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 } ) {
|
||||
my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
|
||||
@{ $WriteMakefileArgs{PREREQ_PM} }{ keys %$build_requires } = values %$build_requires;
|
||||
}
|
||||
|
||||
delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
|
||||
delete $WriteMakefileArgs{MIN_PERL_VERSION}
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
|
||||
delete $WriteMakefileArgs{LICENSE}
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };
|
||||
|
||||
WriteMakefile(%WriteMakefileArgs);
|
||||
|
|
|
@ -2,21 +2,19 @@ Net-Connection-ncnetstat
|
|||
|
||||
Provides a enhances colorized netstat like tool that is capable of doing searches.
|
||||
|
||||
> ncnetstat -p ldap -n -a -C
|
||||
Proto User PID Local Host Port Foreach Host Port State Command
|
||||
tcp6 ldap 1377 * ldap * * LISTEN slapd
|
||||
tcp4 ldap 1377 * ldap * * LISTEN slapd
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 41453 ESTABLISHED slapd
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 62370 ESTABLISHED slapd
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 35181 ESTABLISHED slapd
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 23619 ESTABLISHED slapd
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 23620 ESTABLISHED slapd
|
||||
tcp4 nslcd 1386 127.0.0.1 41453 127.0.0.1 ldap ESTABLISHED nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 62370 127.0.0.1 ldap ESTABLISHED nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 35181 127.0.0.1 ldap ESTABLISHED nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 23619 127.0.0.1 ldap ESTABLISHED nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 23620 127.0.0.1 ldap ESTABLISHED nslcd
|
||||
tcp4 ldap 1377 192.168.15.2 ldap 192.168.14.2 39821 ESTABLISHED slapd
|
||||
> ncnetstat -W --Cl --pct -p ldap -n
|
||||
Proto User PID Local Host Port Remote Host Port State WChan CPU% Mem% Command
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 41453 ESTABLISHED uwait 0.00 0.03 /usr/local/libexec/slapd -u ldap -g ldap
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 62370 ESTABLISHED uwait 0.00 0.03 /usr/local/libexec/slapd -u ldap -g ldap
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 35181 ESTABLISHED uwait 0.00 0.03 /usr/local/libexec/slapd -u ldap -g ldap
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 23619 ESTABLISHED uwait 0.00 0.03 /usr/local/libexec/slapd -u ldap -g ldap
|
||||
tcp4 ldap 1377 127.0.0.1 ldap 127.0.0.1 23620 ESTABLISHED uwait 0.00 0.03 /usr/local/libexec/slapd -u ldap -g ldap
|
||||
tcp4 nslcd 1386 127.0.0.1 41453 127.0.0.1 ldap ESTABLISHED nanslp 0.00 0.02 /usr/local/sbin/nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 62370 127.0.0.1 ldap ESTABLISHED nanslp 0.00 0.02 /usr/local/sbin/nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 35181 127.0.0.1 ldap ESTABLISHED nanslp 0.00 0.02 /usr/local/sbin/nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 23619 127.0.0.1 ldap ESTABLISHED nanslp 0.00 0.02 /usr/local/sbin/nslcd
|
||||
tcp4 nslcd 1386 127.0.0.1 23620 127.0.0.1 ldap ESTABLISHED nanslp 0.00 0.02 /usr/local/sbin/nslcd
|
||||
tcp4 ldap 1377 192.168.15.2 ldap 192.168.14.2 39821 ESTABLISHED uwait 0.00 0.03 /usr/local/libexec/slapd -u ldap -g ldap
|
||||
|
||||
The search criteria can be any of the following.
|
||||
|
||||
|
@ -24,7 +22,13 @@ CIDR
|
|||
port
|
||||
host
|
||||
PTR
|
||||
pctcpu
|
||||
pctmem
|
||||
Regex PTR
|
||||
state
|
||||
UID
|
||||
username
|
||||
wait channel
|
||||
|
||||
TODO
|
||||
|
||||
|
@ -62,6 +66,9 @@ You can also look for information at:
|
|||
Search CPAN
|
||||
https://metacpan.org/release/Net-Connection-ncnetstat
|
||||
|
||||
Repository
|
||||
https://github.com/VVelox/Net-Connection-ncnetstat
|
||||
|
||||
|
||||
LICENSE AND COPYRIGHT
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!perl
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
@ -6,20 +6,23 @@ use Getopt::Long;
|
|||
use Net::Connection::ncnetstat;
|
||||
|
||||
sub version{
|
||||
print "ncnetstat v. 0.0.0\n";
|
||||
print "ncnetstat v. 0.4.0\n";
|
||||
}
|
||||
|
||||
sub help{
|
||||
print '
|
||||
-a Show all connections.
|
||||
--drp Don\'t resolve port names.
|
||||
--drp Do not resolve port names.
|
||||
--dump Show the Net::Connection::Match filter and exit.
|
||||
-i Invert the sort.
|
||||
-l Show the listening ports.
|
||||
-n Don\' resolve the PTRs.
|
||||
--nc Don\'t use colors.
|
||||
-n Do not resolve the PTRs.
|
||||
--nc Do not use colors.
|
||||
--pct Show memory and CPU usage percent.
|
||||
-S <sort> The Net::Connection::Sort to use.
|
||||
-t Show only TCP connections.
|
||||
-u Show only UDP connections.
|
||||
-W Show the wchan.
|
||||
|
||||
-c <CIDRs> A comma seperated list of CIDRs to search for.
|
||||
--ci Invert the CIDR search.
|
||||
|
@ -27,11 +30,23 @@ sub help{
|
|||
-C Show the command to the first space.
|
||||
--Cl Show the whole command.
|
||||
|
||||
--cmd <cmds> A comma seperated list of commands to search for.
|
||||
--cmdi Invert the command search.
|
||||
|
||||
--cpu <pct> Show connections belonging to procs matching this CPU usage percent.
|
||||
--cpui Invert the CPU search.
|
||||
|
||||
--mem <pct> Show connections belonging to procs matching this memory usage percent.
|
||||
--memi Invert the memory usage search.
|
||||
|
||||
-p <ports> A comma seperated list of ports to search for.
|
||||
--pi Invert the port search.
|
||||
|
||||
-P <protocols> A comma seperated list of protocols to search for.
|
||||
--Pi Invert your protocol search.
|
||||
-P <protos> A comma seperated list of protocols to search for.
|
||||
--Pi Invert your protocol search.
|
||||
|
||||
--pid <pids> A comma separated list of PIDs to search for.
|
||||
--pidi Invert the pid search.
|
||||
|
||||
--ptrr <rgx> A comma seperated list of regex to use for a PTR search.
|
||||
--ptrri Invert the RegexPTR search.
|
||||
|
@ -50,12 +65,15 @@ sub help{
|
|||
-s <states> A comma seperated list of states to search for.
|
||||
--si Invert the state search.
|
||||
|
||||
-u <users> A comma seperated list of usernames to search for.
|
||||
--ui Invert the username search.
|
||||
-U <users> A comma seperated list of usernames to search for.
|
||||
--Ui Invert the username search.
|
||||
|
||||
--uid <uids> A comma separated list of UIDs to search for.
|
||||
--uidi Invert the UID search.
|
||||
|
||||
-w <rgx> A comma separated list of regexp to use for matching wchan values.
|
||||
--wi Invert the wchan search.
|
||||
|
||||
The default available sort methods are as below.
|
||||
host_f foreign host
|
||||
host_fl foreign host, local host
|
||||
|
@ -71,7 +89,15 @@ ptr_f foreign PTR
|
|||
ptr_l local PTR
|
||||
state state
|
||||
uid user ID
|
||||
unsorted Unsorted ((default))
|
||||
user username
|
||||
|
||||
For CPU, memory, PID, and UID searches, the equalities below can be
|
||||
used, by directly prepending them to the number.
|
||||
<
|
||||
<=
|
||||
>
|
||||
>=
|
||||
';
|
||||
}
|
||||
|
||||
|
@ -81,7 +107,7 @@ my $udp=0;
|
|||
my $help=0;
|
||||
my $version=0;
|
||||
my $dont_resolve_ports=0;
|
||||
my $sort='host_fl';
|
||||
my $sort='unsorted';
|
||||
my $cidr_string;
|
||||
my $lcidr_string;
|
||||
my $rcidr_string;
|
||||
|
@ -118,6 +144,19 @@ my $uid_string;
|
|||
my $uid_invert=0;
|
||||
my $users_string;
|
||||
my $users_invert=0;
|
||||
my $pids_string;
|
||||
my $pids_invert=0;
|
||||
my $commands_string;
|
||||
my $commands_invert;
|
||||
my $wchan_string;
|
||||
my $wchan_invert=0;
|
||||
my $wchan_show=0;
|
||||
my $pct_show=0;
|
||||
my $cpu_string;
|
||||
my $cpu_invert=0;
|
||||
my $mem_string;
|
||||
my $mem_invert=0;
|
||||
my $dump=0;
|
||||
|
||||
# get the commandline options
|
||||
Getopt::Long::Configure ('no_ignore_case');
|
||||
|
@ -146,6 +185,8 @@ GetOptions(
|
|||
'si' => \$states_invert,
|
||||
'P=s' => \$protocols_string,
|
||||
'Pi' => \$protocols_invert,
|
||||
'pid=s' => \$pids_string,
|
||||
'pidi' => \$pids_invert,
|
||||
'ptrr=s' => \$ptrrs_string,
|
||||
'ptr=s' => \$ptrs_string,
|
||||
'ptri' => \$ptrs_invert,
|
||||
|
@ -164,8 +205,19 @@ GetOptions(
|
|||
'Cl' => \$command_long,
|
||||
'uid=s' => \$uid_string,
|
||||
'uidi'=> \$uid_invert,
|
||||
'u=s' => \$users_string,
|
||||
'ui' => \$users_invert,
|
||||
'U=s' => \$users_string,
|
||||
'Ui' => \$users_invert,
|
||||
'cmd=s' => \$commands_string,
|
||||
'cmdi' => \$commands_invert,
|
||||
'w=s' => \$wchan_string,
|
||||
'wi' => \$wchan_invert,
|
||||
'W' => \$wchan_show,
|
||||
'pct' => \$pct_show,
|
||||
'cpu=s' => \$cpu_string,
|
||||
'cpui' => \$cpu_invert,
|
||||
'mem=s' => \$mem_string,
|
||||
'memi' => \$mem_invert,
|
||||
'dump' => \$dump,
|
||||
);
|
||||
|
||||
my @filters;
|
||||
|
@ -182,28 +234,46 @@ if ( $help ){
|
|||
exit;
|
||||
}
|
||||
|
||||
#
|
||||
# XOR various command line options
|
||||
#
|
||||
if (defined( $ENV{'ncnetstat_pct'} )) {
|
||||
$pct_show= $pct_show ^ $ENV{'ncnetstat_pct'};
|
||||
}
|
||||
if (defined( $ENV{'ncnetstat_C'} )) {
|
||||
$command = $command ^ $ENV{'ncnetstat_C'};
|
||||
}
|
||||
if (defined( $ENV{'ncnetstat_Cl'} )) {
|
||||
$command_long = $command_long ^ $ENV{'ncnetstat_Cl'};
|
||||
}
|
||||
if (defined( $ENV{'ncnetstat_W'} )) {
|
||||
$wchan_show = $wchan_show ^ $ENV{'ncnetstat_W'};
|
||||
}
|
||||
|
||||
|
||||
# add the filters for the -l and -a option
|
||||
if (
|
||||
( ! $all ) &&
|
||||
( ! $listening )
|
||||
){
|
||||
# If -a is not given, we don't want the listen ports
|
||||
push( @filters, {
|
||||
push( @filters,
|
||||
{
|
||||
type=>'Ports',
|
||||
invert=>1,
|
||||
args=>{
|
||||
ports=>[
|
||||
'*',
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
type=>'States',
|
||||
invert=>1,
|
||||
args=>{
|
||||
states=>['LISTEN']
|
||||
}
|
||||
},
|
||||
{
|
||||
type=>'Ports',
|
||||
invert=>1,
|
||||
args=>{
|
||||
fports=>[
|
||||
'*',
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}elsif(
|
||||
$listening &&
|
||||
|
@ -431,6 +501,81 @@ if ( defined( $lptrs_string ) ){
|
|||
);
|
||||
}
|
||||
|
||||
#
|
||||
# Handle the PID searches
|
||||
#
|
||||
if ( defined( $pids_string ) ){
|
||||
my @pids=split(/\,/, $pids_string);
|
||||
push( @filters, {
|
||||
type=>'PID',
|
||||
invert=>$pids_invert,
|
||||
args=>{
|
||||
pids=>\@pids,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#
|
||||
# Handle the command searches
|
||||
#
|
||||
if ( defined( $commands_string ) ){
|
||||
my @commands=split(/\,/, $commands_string);
|
||||
push( @filters, {
|
||||
type=>'Command',
|
||||
invert=>$commands_invert,
|
||||
args=>{
|
||||
commands=>\@commands,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#
|
||||
# Handle the wait channel searches
|
||||
#
|
||||
if ( defined( $wchan_string ) ){
|
||||
my @wchans=split(/\,/, $wchan_string);
|
||||
push( @filters, {
|
||||
type=>'WChan',
|
||||
invert=>$wchan_invert,
|
||||
args=>{
|
||||
wchans=>\@wchans,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#
|
||||
# Handle the pctcpu searches
|
||||
#
|
||||
if ( defined( $cpu_string ) ){
|
||||
my @cpus=split(/\,/, $cpu_string);
|
||||
push( @filters, {
|
||||
type=>'PctCPU',
|
||||
invert=>$cpu_invert,
|
||||
args=>{
|
||||
pctcpus=>\@cpus,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#
|
||||
# Handle the pctmem searches
|
||||
#
|
||||
if ( defined( $mem_string ) ){
|
||||
my @mems=split(/\,/, $mem_string);
|
||||
push( @filters, {
|
||||
type=>'PctMem',
|
||||
invert=>$mem_invert,
|
||||
args=>{
|
||||
pctmems=>\@mems,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
# handle the -t -u options
|
||||
# only add a filter if one is specified...
|
||||
# adding both is just pointless
|
||||
|
@ -485,11 +630,20 @@ if ( $command_long && ! $command ){
|
|||
$command=1;
|
||||
}
|
||||
|
||||
#dump the filters if asked
|
||||
if ($dump) {
|
||||
use Data::Dumper;
|
||||
print Dumper( \@filters );
|
||||
exit;
|
||||
}
|
||||
|
||||
my $ncnetstat=Net::Connection::ncnetstat->new(
|
||||
{
|
||||
ptr=>$ptr,
|
||||
command=>$command,
|
||||
command_long=>$command_long,
|
||||
wchan=>$wchan_show,
|
||||
pct=>$pct_show,
|
||||
sorter=>{
|
||||
invert=>$invert,
|
||||
type=>$sort,
|
||||
|
@ -510,7 +664,7 @@ ncnetstat - a netstat like utility that supports color and searching
|
|||
ncnetstat [B<-a>] [B<--drp>] [B<-l>] [B<-n>] [B<--nc>] [B<-S <sort>>] [B<-t>] [B<-u>]
|
||||
[B<-c <CIDRs>>] [B<--ci -p <ports>>] [B<--pi>] [B<-P <protocols>>] [B<--Pi>]
|
||||
[B<--ptr <PTRs>>] [B<--ptri>] [B<--lptr <PTRs>>] [B<--lptri>] [B<--rptr <PTRs>>] [B<--rptri>]
|
||||
[B<-s <states>>] [B<--si>]
|
||||
[B<-s <states>>] [B<--si>] ...
|
||||
|
||||
=head1 FLAGS
|
||||
|
||||
|
@ -534,6 +688,22 @@ Show the command to the first space.
|
|||
|
||||
Show the whole command.
|
||||
|
||||
=head2 --cmd <cmds>
|
||||
|
||||
A comma seperated list of commands to search for.
|
||||
|
||||
=head2 --cmdi
|
||||
|
||||
Invert the command search.
|
||||
|
||||
=head2 --cpu <pct>
|
||||
|
||||
Show connections belonging to procs matching this CPU usage percent.
|
||||
|
||||
=head2--cpui
|
||||
|
||||
Invert the CPU search.
|
||||
|
||||
=head2 --drp
|
||||
|
||||
Don't resolve port names.
|
||||
|
@ -546,6 +716,15 @@ Invert the sort.
|
|||
|
||||
Show the listening ports.
|
||||
|
||||
=head2 --mem <pct>
|
||||
|
||||
Show connections belonging to procs matching this memory usage percent.
|
||||
|
||||
|
||||
=head2 --memi
|
||||
|
||||
Invert the memory usage search.
|
||||
|
||||
=head2 -n
|
||||
|
||||
Don't resolve the PTRs.
|
||||
|
@ -558,6 +737,10 @@ Don't use colors.
|
|||
|
||||
A comma seperated list of ports to search for.
|
||||
|
||||
=head2 --pct
|
||||
|
||||
Show memory and CPU usage of the process that has the connection.
|
||||
|
||||
=head2 --pi
|
||||
|
||||
Invert the port search.
|
||||
|
@ -570,6 +753,14 @@ A comma seperated list of protocols to search for.
|
|||
|
||||
Invert your protocol search.
|
||||
|
||||
=head2 --pid <pids>
|
||||
|
||||
A comma separated list of PIDs to search for.
|
||||
|
||||
=head2 --pidi
|
||||
|
||||
Invert the pid search.
|
||||
|
||||
=head2 --ptr <PTRs>
|
||||
|
||||
A comma seperated list of PTRs to search for.
|
||||
|
@ -578,6 +769,14 @@ A comma seperated list of PTRs to search for.
|
|||
|
||||
Invert the PTR search.
|
||||
|
||||
=head2 --ptrr <rgx>
|
||||
|
||||
A comma seperated list of regex to use for a PTR search.
|
||||
|
||||
=head2 --ptrri
|
||||
|
||||
Invert the RegexPTR search.
|
||||
|
||||
=head2 --lptr <PTRs>
|
||||
|
||||
A comma seperated list of local PTRs to search for.
|
||||
|
@ -586,6 +785,22 @@ A comma seperated list of local PTRs to search for.
|
|||
|
||||
Invert the local PTR search.
|
||||
|
||||
=head2 --lptrr <rgx>
|
||||
|
||||
A comma seperated list of regex to use for a local PTR search.
|
||||
|
||||
=head2 --lptrri
|
||||
|
||||
Invert the local RegexPTR search.
|
||||
|
||||
=head2 --rptr <PTRs>
|
||||
|
||||
A comma seperated list of remote PTRs to search for.
|
||||
|
||||
=head2 --rptri
|
||||
|
||||
Invert the remote PTR search.
|
||||
|
||||
=head2 --rptr <PTRs>
|
||||
|
||||
A comma seperated list of remote PTRs to search for.
|
||||
|
@ -632,6 +847,47 @@ Show only TCP connections.
|
|||
|
||||
Show only UDP connections.
|
||||
|
||||
=head2 -U <users>
|
||||
|
||||
A comma seperated list of usernames to search for.
|
||||
|
||||
=head2 --Ui
|
||||
|
||||
Invert the username search.
|
||||
|
||||
=head2 --uid <uids>
|
||||
|
||||
A comma separated list of UIDs to search for.
|
||||
|
||||
=head2 --uidi
|
||||
|
||||
Invert the UID search.
|
||||
|
||||
=head2 -W
|
||||
|
||||
Show the wait channel.
|
||||
|
||||
=head2 -w <rgx>
|
||||
|
||||
A comma separated list of regexp to use for matching wchan values.
|
||||
|
||||
=head2 --wi
|
||||
|
||||
Invert the wchan search
|
||||
|
||||
=head1 PID/UID/CPU/Mem EQUALITIES
|
||||
|
||||
For some searches, the equalities below can be used, by
|
||||
directly prepending them to the number.
|
||||
|
||||
<
|
||||
<=
|
||||
>
|
||||
>=
|
||||
|
||||
So if you wanted to find every connection from a UID greater than 1000, would
|
||||
do '--uid \>1000'.
|
||||
|
||||
=head1 ENVIRONMENT VARIABLES
|
||||
|
||||
=head2 NCNETSTAT_invert
|
||||
|
@ -660,21 +916,45 @@ A space-separated list of nameservers to query used by L<Net::DNS::Resolver>.
|
|||
There are a few more possible ones, but this is the most useful one and that documentation
|
||||
really belongs to that module.
|
||||
|
||||
=head2 ncnetstat_C
|
||||
|
||||
Used to xor the -C switch.
|
||||
|
||||
Set to either 0 or 1, boolean, for setting the default.
|
||||
|
||||
=head2 ncnetstat_Cl
|
||||
|
||||
Used to xor the --Cl switch.
|
||||
|
||||
Set to either 0 or 1, boolean, for setting the default.
|
||||
|
||||
=head2 ncnetstat_W
|
||||
|
||||
Used to xor the -W switch.
|
||||
|
||||
Set to either 0 or 1, boolean, for setting the default.
|
||||
|
||||
=head2 ncnetstat_pct
|
||||
|
||||
Used to xor the --pct switch.
|
||||
|
||||
Set to either 0 or 1, boolean, for setting the default.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
ncnestat -s established,time_wait
|
||||
ncnetstat -s established,time_wait
|
||||
|
||||
Return a list of connection that are in the established or time_wait state.
|
||||
|
||||
ncnestat -c ::/0
|
||||
ncnetstat -c ::/0
|
||||
|
||||
Return a list of all IPv6 addresses.
|
||||
|
||||
ncnestat -c ::1/128,127.0.0.1/32
|
||||
ncnetstat -c ::1/128,127.0.0.1/32
|
||||
|
||||
Return all connections to localhost.
|
||||
|
||||
ncnestat -c 192.168.15.2/32 -l
|
||||
ncnetstat -c 192.168.15.2/32 -l
|
||||
|
||||
Display all connections listening explicitly on 192.168.15.2.
|
||||
|
||||
|
@ -695,4 +975,18 @@ Find connections to/from IPs that have a PTR record of foo.bar.
|
|||
|
||||
Find connections to/from IPs that do not have a PTR record of foo.bar.
|
||||
|
||||
ncnetstat -n --uid '>1000' --Cl
|
||||
|
||||
Show every connection by a user with a UID greater than 1000, do not resolve
|
||||
PTR info and print the whole command.
|
||||
|
||||
ncnetstat -U www -p 80,443 --pi
|
||||
|
||||
Show every connecttion by the user www that is not a HTTP or HTTPS connection.
|
||||
|
||||
ncnetstat --cpu '>5' --Cl --pct -W
|
||||
|
||||
Search for connections from procs using more than 5% of the CPU time. Show memory
|
||||
and CPU usage as well whole command and wait channel.
|
||||
|
||||
=cut
|
||||
|
|
|
@ -6,10 +6,14 @@ use warnings;
|
|||
use Net::Connection;
|
||||
use Net::Connection::Match;
|
||||
use Net::Connection::Sort;
|
||||
use Net::Connection::lsof;
|
||||
use Text::Table;
|
||||
use Term::ANSIColor;
|
||||
use Proc::ProcessTable;
|
||||
use Text::ANSITable;
|
||||
|
||||
# use Net::Connection::FreeBSD_sockstat if possible
|
||||
#use if $^O eq 'freebsd', 'Net::Connection::FreeBSD_sockstat';
|
||||
#use if $^O ne 'freebsd', 'Net::Connection::lsof';
|
||||
use Net::Connection::lsof;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
@ -17,11 +21,11 @@ Net::Connection::ncnetstat - The backend for ncnetstat, the colorized and enhanc
|
|||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.1.0
|
||||
Version 0.8.0
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.1.0';
|
||||
our $VERSION = '0.8.0';
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
@ -44,6 +48,8 @@ our $VERSION = '0.1.0';
|
|||
ptr=>1,
|
||||
command=>1,
|
||||
command_long=>0,
|
||||
wchan=>0,
|
||||
pct_show=>1,
|
||||
sorter=>{
|
||||
invert=>0,
|
||||
type=>'host_lf',
|
||||
|
@ -82,6 +88,10 @@ This is the hash to pass to L<Net::Connection::Match>.
|
|||
|
||||
By default this is undef and that module won't be used.
|
||||
|
||||
=head4 no_pid_user
|
||||
|
||||
Don't show the PID or UID/user colomn.
|
||||
|
||||
=head4 sorter
|
||||
|
||||
This is what is to be passed to L<Net::Connection::Sorter>.
|
||||
|
@ -89,50 +99,65 @@ This is what is to be passed to L<Net::Connection::Sorter>.
|
|||
The default is as below.
|
||||
|
||||
{
|
||||
type=>'host_fl',
|
||||
type=>'unsorted',
|
||||
invert=>0,
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub new{
|
||||
sub new {
|
||||
my %args;
|
||||
if(defined($_[1])){
|
||||
%args= %{$_[1]};
|
||||
};
|
||||
if ( defined( $_[1] ) ) {
|
||||
%args = %{ $_[1] };
|
||||
}
|
||||
|
||||
if (! defined( $args{sorter} ) ){
|
||||
$args{sorter}={
|
||||
type=>'host_fl',
|
||||
invert=>0,
|
||||
};
|
||||
if ( !defined( $args{sorter} ) ) {
|
||||
$args{sorter} = {
|
||||
type => 'unsorted',
|
||||
invert => 0,
|
||||
};
|
||||
}
|
||||
|
||||
my $self = {
|
||||
invert=>0,
|
||||
sorter=>Net::Connection::Sort->new( $args{sorter} ),
|
||||
ptr=>1,
|
||||
command=>0,
|
||||
command_long=>0,
|
||||
};
|
||||
bless $self;
|
||||
invert => 0,
|
||||
sorter => Net::Connection::Sort->new( $args{sorter} ),
|
||||
ptr => 1,
|
||||
command => 0,
|
||||
command_long => 0,
|
||||
wchan => 0,
|
||||
pct => 0,
|
||||
no_pid_user => 0,
|
||||
};
|
||||
bless $self;
|
||||
|
||||
if ( defined( $args{match} ) ){
|
||||
$self->{match}=Net::Connection::Match->new( $args{match} );
|
||||
if ( defined( $args{match} ) ) {
|
||||
$self->{match} = Net::Connection::Match->new( $args{match} );
|
||||
}
|
||||
|
||||
if ( defined( $args{ptr} )){
|
||||
$self->{ptr}=$args{ptr};
|
||||
if ( defined( $args{ptr} ) ) {
|
||||
$self->{ptr} = $args{ptr};
|
||||
}
|
||||
|
||||
if ( defined( $args{command} ) ){
|
||||
$self->{command}=$args{command};
|
||||
if ( defined( $args{command} ) ) {
|
||||
$self->{command} = $args{command};
|
||||
}
|
||||
|
||||
if ( defined( $args{command_long} ) ){
|
||||
$self->{command_long}=$args{command_long};
|
||||
if ( defined( $args{pct} ) ) {
|
||||
$self->{pct} = $args{pct};
|
||||
}
|
||||
|
||||
|
||||
if ( defined( $args{wchan} ) ) {
|
||||
$self->{wchan} = $args{wchan};
|
||||
}
|
||||
|
||||
if ( defined( $args{command_long} ) ) {
|
||||
$self->{command_long} = $args{command_long};
|
||||
}
|
||||
|
||||
if ( defined( $args{no_pid_user} ) ) {
|
||||
$self->{no_pid_user} = $args{no_pid_user};
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
@ -144,169 +169,291 @@ This runs it and returns a string.
|
|||
|
||||
=cut
|
||||
|
||||
sub run{
|
||||
my $self=$_[0];
|
||||
|
||||
my @objects = &lsof_to_nc_objects;
|
||||
sub run {
|
||||
my $self = $_[0];
|
||||
|
||||
my @objects;
|
||||
# if ( $^O !~ /freebsd/ ) {
|
||||
@objects = &lsof_to_nc_objects;
|
||||
# }
|
||||
# else {
|
||||
# @objects = &sockstat_to_nc_objects;
|
||||
# }
|
||||
|
||||
my @found;
|
||||
if (defined( $self->{match} )){
|
||||
foreach my $conn (@objects){
|
||||
if( $self->{match}->match( $conn ) ){
|
||||
if ( defined( $self->{match} ) ) {
|
||||
foreach my $conn (@objects) {
|
||||
if ( $self->{match}->match($conn) ) {
|
||||
push( @found, $conn );
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@found=@objects;
|
||||
}
|
||||
else {
|
||||
@found = @objects;
|
||||
}
|
||||
|
||||
@found=$self->{sorter}->sorter( \@found );
|
||||
@found = $self->{sorter}->sorter( \@found );
|
||||
|
||||
my @headers=(
|
||||
color('underline white').'Proto'.color('reset'),
|
||||
color('underline white').'User'.color('reset'),
|
||||
color('underline white').'PID'.color('reset'),
|
||||
color('underline white').'Local Host'.color('reset'),
|
||||
color('underline white').'Port'.color('reset'),
|
||||
color('underline white').'Foreach Host'.color('reset'),
|
||||
color('underline white').'Port'.color('reset'),
|
||||
color('underline white').'State'.color('reset'),
|
||||
);
|
||||
my $tb = Text::ANSITable->new;
|
||||
$tb->border_style('ASCII::None');
|
||||
$tb->color_theme('NoColor');
|
||||
|
||||
if ( $self->{command} ){
|
||||
push( @headers, color('underline white').'Command'.color('reset') )
|
||||
my @headers;
|
||||
my $header_int = 0;
|
||||
push( @headers, 'Proto' );
|
||||
$tb->set_column_style( $header_int, pad => 0 );
|
||||
$header_int++;
|
||||
if ( !$self->{no_pid_user} ) {
|
||||
push( @headers, 'User' );
|
||||
$tb->set_column_style( $header_int, pad => 1 );
|
||||
$header_int++;
|
||||
push( @headers, 'PID' );
|
||||
$tb->set_column_style( $header_int, pad => 0 );
|
||||
$header_int++;
|
||||
}
|
||||
push( @headers, 'Local Host' );
|
||||
$tb->set_column_style( $header_int, pad => 1, formats => [ [ wrap => { ansi => 1, mb => 1 } ] ] );
|
||||
$header_int++;
|
||||
push( @headers, 'L Port' );
|
||||
$tb->set_column_style( $header_int, pad => 0 );
|
||||
$header_int++;
|
||||
push( @headers, 'Remote Host' );
|
||||
$tb->set_column_style( $header_int, pad => 1, formats => [ [ wrap => { ansi => 1, mb => 1 } ] ] );
|
||||
$header_int++;
|
||||
push( @headers, 'R Port' );
|
||||
$tb->set_column_style( $header_int, pad => 0 );
|
||||
$header_int++;
|
||||
push( @headers, 'State' );
|
||||
$tb->set_column_style( $header_int, pad => 1 );
|
||||
$header_int++;
|
||||
|
||||
my $padding = 0;
|
||||
if ( $self->{wchan} ) {
|
||||
if ( ( $header_int % 2 ) != 0 ) {
|
||||
$padding = 1;
|
||||
}
|
||||
push( @headers, 'WChan' );
|
||||
$tb->set_column_style( $header_int, pad => $padding );
|
||||
$header_int++;
|
||||
}
|
||||
|
||||
my $tb = Text::Table->new( @headers );
|
||||
if ( $self->{pct} ) {
|
||||
if ( ( $header_int % 2 ) != 0 ) {
|
||||
$padding = 1;
|
||||
}
|
||||
else {
|
||||
$padding = 0;
|
||||
}
|
||||
push( @headers, 'CPU%' );
|
||||
$tb->set_column_style( $header_int, pad => $padding );
|
||||
$header_int++;
|
||||
if ( ( $header_int % 2 ) != 0 ) {
|
||||
$padding = 1;
|
||||
}
|
||||
else {
|
||||
$padding = 0;
|
||||
}
|
||||
push( @headers, 'Mem%' );
|
||||
$tb->set_column_style( $header_int, pad => $padding );
|
||||
$header_int++;
|
||||
}
|
||||
|
||||
if ( $self->{command} ) {
|
||||
if ( ( $header_int % 2 ) != 0 ) {
|
||||
$padding = 1;
|
||||
}
|
||||
else {
|
||||
$padding = 0;
|
||||
}
|
||||
push( @headers, 'Command' );
|
||||
$tb->set_column_style( $header_int, pad => $padding, formats => [ [ wrap => { ansi => 1, mb => 1 } ] ] );
|
||||
$header_int++;
|
||||
}
|
||||
|
||||
$tb->set_column_style( 4, pad => 0 );
|
||||
$tb->set_column_style( 5, pad => 1, formats => [ [ wrap => { ansi => 1, mb => 1 } ] ] );
|
||||
$tb->set_column_style( 6, pad => 0 );
|
||||
$tb->set_column_style( 7, pad => 1 );
|
||||
$tb->set_column_style( 8, pad => 0 );
|
||||
$tb->set_column_style( 9, pad => 1 );
|
||||
$tb->set_column_style( 10, pad => 0 );
|
||||
$tb->set_column_style( 11, pad => 1, formats => [ [ wrap => { ansi => 1, mb => 1 } ] ] );
|
||||
$tb->set_column_style( 12, pad => 0 );
|
||||
$tb->set_column_style( 13, pad => 1 );
|
||||
|
||||
$tb->columns( \@headers );
|
||||
|
||||
# process table stuff if needed
|
||||
my $ppt;
|
||||
my $proctable;
|
||||
my %cmd_cache;
|
||||
if ( $self->{command} ){
|
||||
$ppt=Proc::ProcessTable->new;
|
||||
$proctable=$ppt->table;
|
||||
if ( $self->{command} ) {
|
||||
$ppt = Proc::ProcessTable->new;
|
||||
$proctable = $ppt->table;
|
||||
}
|
||||
|
||||
my @td;
|
||||
foreach my $conn ( @found ){
|
||||
my @new_line=(
|
||||
color('bright_yellow').$conn->proto.color('reset'),
|
||||
);
|
||||
foreach my $conn (@found) {
|
||||
my @new_line = ( color('bright_yellow') . $conn->proto . color('reset'), );
|
||||
|
||||
# handle adding the username or UID if we have one
|
||||
if ( defined( $conn->username ) ){
|
||||
push( @new_line, color('bright_cyan').$conn->username.color('reset'));
|
||||
}else{
|
||||
if ( defined( $conn->uid ) ){
|
||||
push( @new_line, color('bright_cyan').$conn->uid.color('reset'));
|
||||
}else{
|
||||
push( @new_line, '');
|
||||
# don't add the PID or user if requested to
|
||||
if ( !$self->{no_pid_user} ) {
|
||||
|
||||
# handle adding the username or UID if we have one
|
||||
if ( defined( $conn->username ) ) {
|
||||
push( @new_line, color('bright_cyan') . $conn->username . color('reset') );
|
||||
}
|
||||
else {
|
||||
if ( defined( $conn->uid ) ) {
|
||||
push( @new_line, color('bright_cyan') . $conn->uid . color('reset') );
|
||||
}
|
||||
else {
|
||||
push( @new_line, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# handle adding the PID if we have one
|
||||
if ( defined( $conn->pid ) ){
|
||||
push( @new_line, color('bright_red').$conn->pid.color('reset'));
|
||||
$conn->pid;
|
||||
}else{
|
||||
push( @new_line, '');
|
||||
# handle adding the PID if we have one
|
||||
if ( defined( $conn->pid ) ) {
|
||||
push( @new_line, color('bright_red') . $conn->pid . color('reset') );
|
||||
$conn->pid;
|
||||
}
|
||||
else {
|
||||
push( @new_line, '' );
|
||||
}
|
||||
}
|
||||
|
||||
# Figure out what we are using for the local host
|
||||
my $local;
|
||||
if ( defined( $conn->local_ptr ) && $self->{ptr} ){
|
||||
$local=$conn->local_ptr;
|
||||
}else{
|
||||
$local=$conn->local_host;
|
||||
if ( defined( $conn->local_ptr ) && $self->{ptr} ) {
|
||||
$local = $conn->local_ptr;
|
||||
}
|
||||
else {
|
||||
$local = $conn->local_host;
|
||||
}
|
||||
|
||||
# Figure out what we are using for the foriegn host
|
||||
my $foreign;
|
||||
if ( defined( $conn->foreign_ptr ) && $self->{ptr} ){
|
||||
$foreign=$conn->foreign_ptr;
|
||||
}else{
|
||||
$foreign=$conn->foreign_host;
|
||||
if ( defined( $conn->foreign_ptr ) && $self->{ptr} ) {
|
||||
$foreign = $conn->foreign_ptr;
|
||||
}
|
||||
else {
|
||||
$foreign = $conn->foreign_host;
|
||||
}
|
||||
|
||||
# Figure out what we are using for the local port
|
||||
my $lport;
|
||||
if ( defined( $conn->local_port_name ) ){
|
||||
$lport=$conn->local_port_name;
|
||||
}else{
|
||||
$lport=$conn->local_port;
|
||||
if ( defined( $conn->local_port_name ) ) {
|
||||
$lport = $conn->local_port_name;
|
||||
}
|
||||
else {
|
||||
$lport = $conn->local_port;
|
||||
}
|
||||
|
||||
# Figure out what we are using for the foreign port
|
||||
my $fport;
|
||||
if ( defined( $conn->foreign_port_name ) ){
|
||||
$fport=$conn->foreign_port_name;
|
||||
}else{
|
||||
$fport=$conn->foreign_port;
|
||||
if ( defined( $conn->foreign_port_name ) ) {
|
||||
$fport = $conn->foreign_port_name;
|
||||
}
|
||||
else {
|
||||
$fport = $conn->foreign_port;
|
||||
}
|
||||
|
||||
push(
|
||||
@new_line,
|
||||
color('bright_green').$local.color('reset'),
|
||||
color('green').$lport.color('reset'),
|
||||
color('bright_magenta').$foreign.color('reset'),
|
||||
color('magenta').$fport.color('reset'),
|
||||
color('bright_blue').$conn->state.color('reset'),
|
||||
);
|
||||
push( @new_line,
|
||||
color('bright_green') . $local . color('reset'),
|
||||
color('green') . $lport . color('reset'),
|
||||
color('bright_magenta') . $foreign . color('reset'),
|
||||
color('magenta') . $fport . color('reset'),
|
||||
color('bright_blue') . $conn->state . color('reset'),
|
||||
);
|
||||
|
||||
# handle the wchan bit if needed
|
||||
if ( $self->{wchan}
|
||||
&& defined( $conn->wchan ) )
|
||||
{
|
||||
push( @new_line, color('bright_yellow') . $conn->wchan . color('reset') );
|
||||
}
|
||||
|
||||
# handle the percent stuff if needed
|
||||
if ( $self->{pct}
|
||||
&& defined( $conn->pctcpu ) )
|
||||
{
|
||||
push( @new_line, color('bright_cyan') . sprintf( '%.2f', $conn->pctcpu ) . color('reset') );
|
||||
}
|
||||
|
||||
# handle the percent stuff if needed
|
||||
if ( $self->{pct}
|
||||
&& defined( $conn->pctmem ) )
|
||||
{
|
||||
push( @new_line, color('bright_green') . sprintf( '%.2f', $conn->pctmem ) . color('reset') );
|
||||
}
|
||||
|
||||
# handle the command portion if needed
|
||||
if (
|
||||
defined( $conn->pid ) &&
|
||||
$self->{command}
|
||||
){
|
||||
if ( defined( $conn->pid )
|
||||
&& $self->{command} )
|
||||
{
|
||||
|
||||
my $loop=1;
|
||||
my $proc=0;
|
||||
while (
|
||||
defined( $proctable->[ $proc ] ) &&
|
||||
$loop
|
||||
){
|
||||
my $loop = 1;
|
||||
my $proc = 0;
|
||||
while ( defined( $proctable->[$proc] )
|
||||
&& $loop )
|
||||
{
|
||||
my $command;
|
||||
if (defined( $cmd_cache{$conn->pid} ) ){
|
||||
push( @new_line, color('bright_red').$cmd_cache{$conn->pid}.color('reset') );
|
||||
$loop=0;
|
||||
}elsif( $proctable->[ $proc ]->pid eq $conn->pid ){
|
||||
if ( $proctable->[ $proc ]->{'cmndline'} =~ /^$/ ){
|
||||
if ( defined( $cmd_cache{ $conn->pid } ) ) {
|
||||
push( @new_line, color('bright_red') . $cmd_cache{ $conn->pid } . color('reset') );
|
||||
$loop = 0;
|
||||
}
|
||||
elsif ( defined( $conn->proc ) ) {
|
||||
my $command = $conn->proc;
|
||||
if ( !$self->{command_long} ) {
|
||||
$command =~ s/\ .*//;
|
||||
}
|
||||
$cmd_cache{ $conn->pid } = $command;
|
||||
push( @new_line, color('bright_red') . $cmd_cache{ $conn->pid } . color('reset') );
|
||||
$loop = 0,;
|
||||
}
|
||||
elsif ( $proctable->[$proc]->pid eq $conn->pid ) {
|
||||
if ( $proctable->[$proc]->{'cmndline'} =~ /^$/ ) {
|
||||
|
||||
#kernel process
|
||||
$cmd_cache{$conn->pid}=color('bright_red').'['.$proctable->[ $proc ]->{'fname'}.']'.color('reset');
|
||||
}elsif( $self->{command_long} ){
|
||||
$cmd_cache{$conn->pid}=color('bright_red').$proctable->[ $proc ]->{'cmndline'}.color('reset');
|
||||
}elsif( $proctable->[ $proc ]->{'cmndline'} =~ /^\//){
|
||||
$cmd_cache{ $conn->pid }
|
||||
= color('bright_red') . '[' . $proctable->[$proc]->{'fname'} . ']' . color('reset');
|
||||
}
|
||||
elsif ( $self->{command_long} ) {
|
||||
$cmd_cache{ $conn->pid }
|
||||
= color('bright_red') . $proctable->[$proc]->{'cmndline'} . color('reset');
|
||||
}
|
||||
elsif ( $proctable->[$proc]->{'cmndline'} =~ /^\// ) {
|
||||
|
||||
# something ran with a complete path
|
||||
$cmd_cache{$conn->pid}=color('bright_red').$proctable->[ $proc ]->{'fname'}.color('reset');
|
||||
}else{
|
||||
$cmd_cache{ $conn->pid }
|
||||
= color('bright_red') . $proctable->[$proc]->{'fname'} . color('reset');
|
||||
}
|
||||
else {
|
||||
# likely a thread or the like... such as dovecot/auth
|
||||
# just trunkcat everything after the space
|
||||
my $cmd=$proctable->[ $proc ]->{'cmndline'};
|
||||
$cmd=~s/\ +.*//g;
|
||||
$cmd_cache{$conn->pid}=color('bright_red').$cmd.color('reset');
|
||||
my $cmd = $proctable->[$proc]->{'cmndline'};
|
||||
$cmd =~ s/\ +.*//g;
|
||||
$cmd_cache{ $conn->pid } = color('bright_red') . $cmd . color('reset');
|
||||
}
|
||||
|
||||
push( @new_line, $cmd_cache{$conn->pid} );
|
||||
$loop=0;
|
||||
push( @new_line, $cmd_cache{ $conn->pid } );
|
||||
$loop = 0;
|
||||
}
|
||||
|
||||
$proc++;
|
||||
}
|
||||
|
||||
}elsif(
|
||||
( !defined( $conn->pid ) ) &&
|
||||
$self->{command}
|
||||
){
|
||||
push( @new_line, '');
|
||||
}
|
||||
elsif ( ( !defined( $conn->pid ) )
|
||||
&& $self->{command} )
|
||||
{
|
||||
push( @new_line, '' );
|
||||
}
|
||||
|
||||
push( @td, \@new_line );
|
||||
$tb->add_row( \@new_line );
|
||||
}
|
||||
|
||||
$tb->load( @td );
|
||||
|
||||
return $tb;
|
||||
return $tb->draw;
|
||||
}
|
||||
|
||||
=head1 TODO
|
||||
|
@ -343,18 +490,14 @@ You can also look for information at:
|
|||
|
||||
L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-Connection-ncnetstat>
|
||||
|
||||
=item * AnnoCPAN: Annotated CPAN documentation
|
||||
|
||||
L<http://annocpan.org/dist/Net-Connection-ncnetstat>
|
||||
|
||||
=item * CPAN Ratings
|
||||
|
||||
L<https://cpanratings.perl.org/d/Net-Connection-ncnetstat>
|
||||
|
||||
=item * Search CPAN
|
||||
|
||||
L<https://metacpan.org/release/Net-Connection-ncnetstat>
|
||||
|
||||
=item * Repository
|
||||
|
||||
L<https://github.com/VVelox/Net-Connection-ncnetstat>
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
|
|
@ -10,9 +10,15 @@ BEGIN {
|
|||
use_ok( 'Net::Connection::ncnetstat' ) || print "Bail out!\n";
|
||||
}
|
||||
|
||||
my $output_raw=`lsof -i UDP -i TCP -n -l -P`;
|
||||
if ( $? eq 0 ){
|
||||
$extra_tests=2;
|
||||
my $output_raw=`lsof -i UDP -i TCP -n -l -P 2> /dev/null`;
|
||||
if (
|
||||
( $? eq 0 ) ||
|
||||
(
|
||||
( $^O =~ /linux/ ) &&
|
||||
( $? eq 256 )
|
||||
)
|
||||
){
|
||||
$extra_tests=1;
|
||||
my $worked=0;
|
||||
my $ncnetstat;
|
||||
my $tb;
|
||||
|
@ -22,7 +28,6 @@ if ( $? eq 0 ){
|
|||
$worked=1;
|
||||
};
|
||||
ok( $worked eq '1', 'run test') or diag("run died with ".$@);
|
||||
ok( ref($tb) eq 'Text::Table', 'run ref test') or diag("run did not return a Text::Table object");
|
||||
}else{
|
||||
diag('No lsof installed on this system or "lsof -i UDP -i TCP -n -l -P" does not work');
|
||||
}
|
||||
|
|
153
README.md
153
README.md
|
@ -6,12 +6,153 @@ Provides a enhances colorized netstat like tool that is capable of doing searche
|
|||
|
||||
The search criteria can be any of the following.
|
||||
|
||||
CIDR
|
||||
port
|
||||
host
|
||||
PTR
|
||||
state
|
||||
* CIDR
|
||||
* Command
|
||||
* CPU usage percent
|
||||
* port
|
||||
* host
|
||||
* memory usage percent
|
||||
* PID
|
||||
* PTR
|
||||
* state
|
||||
* UID
|
||||
* username
|
||||
* wait channel
|
||||
|
||||
# Command Line Options
|
||||
```
|
||||
-a Show all connections.
|
||||
--drp Do not resolve port names.
|
||||
-i Invert the sort.
|
||||
-l Show the listening ports.
|
||||
-n Do not resolve the PTRs.
|
||||
--nc Do not use colors.
|
||||
--pct Show memory and CPU usage percent.
|
||||
-S <sort> The Net::Connection::Sort to use.
|
||||
-t Show only TCP connections.
|
||||
-u Show only UDP connections.
|
||||
-W Show the wchan.
|
||||
|
||||
-c <CIDRs> A comma seperated list of CIDRs to search for.
|
||||
--ci Invert the CIDR search.
|
||||
|
||||
-C Show the command to the first space.
|
||||
--Cl Show the whole command.
|
||||
|
||||
--cmd <cmds> A comma seperated list of commands to search for.
|
||||
--cmdi Invert the command search.
|
||||
|
||||
--cpu <pct> Show connections belonging to procs matching this CPU usage percent.
|
||||
--cpui Invert the CPU search.
|
||||
|
||||
--mem <pct> Show connections belonging to procs matching this memory usage percent.
|
||||
--memi Invert the memory usage search.
|
||||
|
||||
-p <ports> A comma seperated list of ports to search for.
|
||||
--pi Invert the port search.
|
||||
|
||||
-P <protos> A comma seperated list of protocols to search for.
|
||||
--Pi Invert your protocol search.
|
||||
|
||||
--pid <pids> A comma separated list of PIDs to search for.
|
||||
--pidi Invert the pid search.
|
||||
|
||||
--ptrr <rgx> A comma seperated list of regex to use for a PTR search.
|
||||
--ptrri Invert the RegexPTR search.
|
||||
--lptrr <rgx> A comma seperated list of regex to use for a local PTR search.
|
||||
--lptrri Invert the local RegexPTR search.
|
||||
--rptrr <rgx> A comma seperated list of regex to use for a remote PTR search.
|
||||
--rptrri Invert the remote RegexPTR search.
|
||||
|
||||
--ptr <PTRs> A comma seperated list of PTRs to search for.
|
||||
--ptri Invert the PTR search.
|
||||
--lptr <PTRs> A comma seperated list of local PTRs to search for.
|
||||
--lptri Invert the local PTR search.
|
||||
--rptr <PTRs> A comma seperated list of remote PTRs to search for.
|
||||
--rptri Invert the remote PTR search.
|
||||
|
||||
-s <states> A comma seperated list of states to search for.
|
||||
--si Invert the state search.
|
||||
|
||||
-U <users> A comma seperated list of usernames to search for.
|
||||
--Ui Invert the username search.
|
||||
|
||||
--uid <uids> A comma separated list of UIDs to search for.
|
||||
--uidi Invert the UID search.
|
||||
|
||||
-w <rgx> A comma separated list of regexp to use for matching wchan values.
|
||||
--wi Invert the wchan search.
|
||||
|
||||
The default available sort methods are as below.
|
||||
host_f foreign host
|
||||
host_fl foreign host, local host
|
||||
host_l local host
|
||||
host_lf local host, foreign host
|
||||
pid process ID
|
||||
port_f foreign port, numerically
|
||||
port_fa foreign port, alphabetically
|
||||
port_l local port, numerically
|
||||
port_la local port, alphabetically
|
||||
proto protocol
|
||||
ptr_f foreign PTR
|
||||
ptr_l local PTR
|
||||
state state
|
||||
uid user ID
|
||||
user username
|
||||
|
||||
For CPU, memory, PID, and UID searches, the equalities below can be
|
||||
used, by directly prepending them to the number.
|
||||
<
|
||||
<=
|
||||
>
|
||||
>=
|
||||
```
|
||||
|
||||
# Examples
|
||||
|
||||
ncnetstat -s established,time_wait
|
||||
|
||||
Return a list of connection that are in the established or time_wait state.
|
||||
|
||||
|
||||
ncnetstat -c ::1/128,127.0.0.1/32
|
||||
|
||||
Return all connections to localhost.
|
||||
|
||||
ncnetstat -c 192.168.15.2/32 -l
|
||||
|
||||
Display all connections listening explicitly on 192.168.15.2.
|
||||
|
||||
ncnetstat -S host_f -i
|
||||
|
||||
Sort the connections by the foreign host and invert the results.
|
||||
|
||||
ncnetstat -c 10.0.0.0/24 --ci
|
||||
|
||||
Show connections that are either not locally or remotely part of the
|
||||
10.0.0.0/24 subnet.
|
||||
|
||||
ncnetstat --ptr foo.bar
|
||||
|
||||
Find connections to/from IPs that have a PTR record of foo.bar.
|
||||
|
||||
ncnetstat --ptr foo.bar --ptri
|
||||
|
||||
Find connections to/from IPs that do not have a PTR record of foo.bar.
|
||||
|
||||
ncnetstat -n --uid '>1000' --Cl
|
||||
|
||||
Show every connection by a user with a UID greater than 1000, do not resolve
|
||||
PTR info and print the whole command.
|
||||
|
||||
ncnetstat -U www -p 80,443 --pi
|
||||
|
||||
Show every connecttion by the user www that is not a HTTP or HTTPS connection.
|
||||
|
||||
ncnetstat --cpu '>5' --Cl --pct -W
|
||||
|
||||
Search for connections from procs using more than 5% of the CPU time. Show memory
|
||||
and CPU usage as well whole command and wait channel.
|
||||
|
||||
# Installing
|
||||
|
||||
|
@ -31,7 +172,7 @@ state
|
|||
|
||||
This has been tested as working on Debian 9 minimal.
|
||||
|
||||
apt install perl perl-base perl-modules make cpanminus lsof
|
||||
apt install perl perl-base perl-modules make cpanminus lsof gcc
|
||||
cpanm Net::Connection::ncnetstat
|
||||
# TODO
|
||||
|
||||
|
|
BIN
ncnetstat.png
BIN
ncnetstat.png
Binary file not shown.
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 54 KiB |
Loading…
Reference in New Issue