1#!/usr/bin/env perl
2
3use strict;
4use warnings;
5use Getopt::Long;
6use Net::Connection::ncnetstat;
7
8sub version{
9	print "ncnetstat v. 0.3.1\n";
10}
11
12sub help{
13	print '
14-a         Show all connections.
15--drp      Do not resolve port names.
16--dump     Show the Net::Connection::Match filter and exit.
17-i         Invert the sort.
18-l         Show the listening ports.
19-n         Do not resolve the PTRs.
20--nc       Do not use colors.
21--pct      Show memory and CPU usage percent.
22-S <sort>  The Net::Connection::Sort to use.
23-t         Show only TCP connections.
24-u         Show only UDP connections.
25-W         Show the wchan.
26
27-c <CIDRs>  A comma seperated list of CIDRs to search for.
28--ci        Invert the CIDR search.
29
30-C    Show the command to the first space.
31--Cl  Show the whole command.
32
33--cmd <cmds> A comma seperated list of commands to search for.
34--cmdi       Invert the command search.
35
36--cpu <pct> Show connections belonging to procs matching this CPU usage percent.
37--cpui      Invert the CPU search.
38
39--mem <pct> Show connections belonging to procs matching this memory usage percent.
40--memi      Invert the memory usage search.
41
42-p <ports>  A comma seperated list of ports to search for.
43--pi        Invert the port search.
44
45-P <protos> A comma seperated list of protocols to search for.
46--Pi        Invert your protocol search.
47
48--pid <pids> A comma separated list of PIDs to search for.
49--pidi       Invert the pid search.
50
51--ptrr <rgx>   A comma seperated list of regex to use for a PTR search.
52--ptrri        Invert the RegexPTR search.
53--lptrr <rgx>  A comma seperated list of regex to use for a local PTR search.
54--lptrri       Invert the local RegexPTR search.
55--rptrr <rgx>  A comma seperated list of regex to use for a remote PTR search.
56--rptrri       Invert the remote RegexPTR search.
57
58--ptr <PTRs>   A comma seperated list of PTRs to search for.
59--ptri         Invert the PTR search.
60--lptr <PTRs>  A comma seperated list of local PTRs to search for.
61--lptri        Invert the local PTR search.
62--rptr <PTRs>  A comma seperated list of remote PTRs to search for.
63--rptri        Invert the remote PTR search.
64
65-s <states>  A comma seperated list of states to search for.
66--si         Invert the state search.
67
68-U <users>   A comma seperated list of usernames to search for.
69--Ui         Invert the username search.
70
71--uid <uids> A comma separated list of UIDs to search for.
72--uidi       Invert the UID search.
73
74-w <rgx>     A comma separated list of regexp to use for matching wchan values.
75--wi         Invert the wchan search.
76
77The default available sort methods are as below.
78host_f   foreign host
79host_fl  foreign host, local host
80host_l   local host
81host_lf  local host, foreign host
82pid      process ID
83port_f   foreign port, numerically
84port_fa  foreign port, alphabetically
85port_l   local port, numerically
86port_la  local port, alphabetically
87proto    protocol
88ptr_f    foreign PTR
89ptr_l    local PTR
90state    state
91uid      user ID
92user     username
93
94For CPU, memory, PID, and UID searches, the equalities below can be
95used, by directly prepending them to the number.
96<
97<=
98>
99>=
100';
101}
102
103# command line option holders
104my $tcp=0;
105my $udp=0;
106my $help=0;
107my $version=0;
108my $dont_resolve_ports=0;
109my $sort='host_fl';
110my $cidr_string;
111my $lcidr_string;
112my $rcidr_string;
113my $ports_string;
114my $states_string;
115my $protocols_string;
116my $all=0;
117my $listening;
118my $invert=0;
119my $ptrs_string;
120my $ptrrs_string;
121my $rptrs_string;
122my $lptrs_string;
123my $rptrrs_string;
124my $lptrrs_string;
125my $ports_invert;
126my $rptrs_invert;
127my $lptrs_invert;
128my $rptrrs_invert;
129my $lptrrs_invert;
130my $ptrs_invert;
131my $ptrrs_invert;
132my $cidr_invert;
133my $lcidr_invert;
134my $rcidr_invert;
135my $states_invert;
136my $protocols_invert;
137my $no_color=0;
138my $no_use_ptr=0;
139my $ptr=1;
140my $command=0;
141my $command_long=0;
142my $uid_string;
143my $uid_invert=0;
144my $users_string;
145my $users_invert=0;
146my $pids_string;
147my $pids_invert=0;
148my $commands_string;
149my $commands_invert;
150my $wchan_string;
151my $wchan_invert=0;
152my $wchan_show=0;
153my $pct_show=0;
154my $cpu_string;
155my $cpu_invert=0;
156my $mem_string;
157my $mem_invert=0;
158my $dump=0;
159
160# get the commandline options
161Getopt::Long::Configure ('no_ignore_case');
162Getopt::Long::Configure ('bundling');
163GetOptions(
164		   't'=>\$tcp,
165		   'u'=>\$udp,
166		   'version' => \$version,
167		   'v' => \$version,
168		   'help' => \$help,
169		   'h' => \$help,
170		   'a' => \$all,
171		   'l' => \$listening,
172		   'i' => \$invert,
173		   'drp' => \$dont_resolve_ports,
174		   'c=s' => \$cidr_string,
175		   'ci'=> \$cidr_invert,
176		   'lc=s' => \$lcidr_string,
177		   'lci'=> \$lcidr_invert,
178		   'rc=s' => \$rcidr_string,
179		   'rci'=> \$rcidr_invert,
180		   'S=s' => \$sort,
181		   'p=s' => \$ports_string,
182		   'pi' => \$ports_invert,
183		   's=s' => \$states_string,
184		   'si' => \$states_invert,
185		   'P=s' => \$protocols_string,
186		   'Pi' => \$protocols_invert,
187		   'pid=s' => \$pids_string,
188		   'pidi' => \$pids_invert,
189		   'ptrr=s' => \$ptrrs_string,
190		   'ptr=s' => \$ptrs_string,
191		   'ptri' => \$ptrs_invert,
192		   'ptrri' => \$ptrrs_invert,
193		   'rptrr=s' => \$rptrrs_string,
194		   'rptr=s' => \$rptrs_string,
195		   'rptrri' => \$rptrrs_invert,
196		   'rptri' => \$rptrs_invert,
197		   'lptrr=s' => \$lptrrs_string,
198		   'lptr=s' => \$lptrs_string,
199		   'lptri' => \$lptrs_invert,
200		   'lptrri' => \$lptrrs_invert,
201		   'nc' => \$no_color,
202		   'n' => \$no_use_ptr,
203		   'C' => \$command,
204		   'Cl' => \$command_long,
205		   'uid=s' => \$uid_string,
206		   'uidi'=> \$uid_invert,
207		   'U=s' => \$users_string,
208		   'Ui' => \$users_invert,
209		   'cmd=s' => \$commands_string,
210		   'cmdi' => \$commands_invert,
211		   'w=s' => \$wchan_string,
212		   'wi' => \$wchan_invert,
213		   'W' => \$wchan_show,
214		   'pct' => \$pct_show,
215		   'cpu=s' => \$cpu_string,
216		   'cpui' => \$cpu_invert,
217		   'mem=s' => \$mem_string,
218		   'memi' => \$mem_invert,
219		   'dump' => \$dump,
220		   );
221
222my @filters;
223
224# print the version info if requested
225if ( $version ){
226	&version;
227	exit;
228}
229
230if ( $help ){
231	&version;
232	&help;
233	exit;
234}
235
236#
237# XOR various command line options
238#
239if (defined( $ENV{'ncnetstat_pct'} )) {
240	$pct_show= $pct_show ^ $ENV{'ncnetstat_pct'};
241}
242if (defined( $ENV{'ncnetstat_C'} )) {
243	$command = $command ^ $ENV{'ncnetstat_C'};
244}
245if (defined( $ENV{'ncnetstat_Cl'} )) {
246	$command_long = $command_long ^ $ENV{'ncnetstat_Cl'};
247}
248if (defined( $ENV{'ncnetstat_W'} )) {
249	$wchan_show = $wchan_show ^ $ENV{'ncnetstat_W'};
250}
251
252
253# add the filters for the -l and -a option
254if (
255	( ! $all ) &&
256	( ! $listening )
257	){
258	# If -a is not given, we don't want the listen ports
259	push( @filters,
260		  {
261		   type=>'Ports',
262		   invert=>1,
263		   args=>{
264				  ports=>[
265						   '*',
266						   ],
267				  }
268		   },
269		   {
270					 type=>'States',
271					 invert=>1,
272					 args=>{
273							states=>['LISTEN']
274							}
275					 }
276		 );
277}elsif(
278	   $listening &&
279	   ( ! $all )
280	   ){
281	# if -l we only want the ports in the LISTEN state
282	push( @filters, {
283					 type=>'States',
284					 invert=>0,
285					 args=>{
286							states=>['LISTEN']
287							}
288					 }
289		 );
290}
291
292#
293# Handle stats search
294#
295if ( defined( $states_string ) ){
296	my @states=split(/\,/, $states_string );
297	push( @filters, {
298					 type=>'States',
299					 invert=>$states_invert,
300					 args=>{
301							states=>\@states,
302							},
303					 }
304		 );
305}
306
307#
308# handles the protocol search
309#
310if ( defined( $protocols_string ) ){
311	my @protos=split(/\,/, $protocols_string );
312	push( @filters, {
313					 type=>'Protos',
314					 invert=>$protocols_invert,
315					 args=>{
316							protos=>\@protos,
317							},
318					 }
319		 );
320}
321
322#
323# Handle CIDR searches
324#
325if ( defined( $cidr_string ) ){
326	my @cidrs=split(/\,/, $cidr_string );
327	push( @filters, {
328					 type=>'CIDR',
329					 invert=>$cidr_invert,
330					 args=>{
331							cidrs=>\@cidrs,
332							},
333					 }
334		  );
335}
336
337#
338# Handle UID searches
339#
340if ( defined( $uid_string ) ){
341	my @uids=split(/\,/, $uid_string );
342	push( @filters, {
343					 type=>'UID',
344					 invert=>$uid_invert,
345					 args=>{
346							uids=>\@uids,
347							},
348					 }
349		  );
350}
351
352#
353# Handle username searches
354#
355if ( defined( $users_string ) ){
356	my @users=split(/\,/, $users_string );
357	push( @filters, {
358					 type=>'Username',
359					 invert=>$users_invert,
360					 args=>{
361							usernames=>\@users,
362							},
363					 }
364		  );
365}
366
367#
368# Handle local CIDR searches
369#
370#if ( defined( $lcidr_string ) ){
371#	my @cidrs=split(/\,/, $lcidr_string );
372#	push( @filters, {
373#					 type=>'CIDR',
374#					 invert=>$cidr_invert,
375#					 args=>{
376#							lcidrs=>\@cidrs,
377#							},
378#					 }
379#		  );
380#}
381
382#
383# Handle local CIDR searches
384#
385#if ( defined( $fcidr_string ) ){
386#	my @cidrs=split(/\,/, $fcidr_string );
387#	push( @filters, {
388#					 type=>'CIDR',
389#					 invert=>$cidr_invert,
390#					 args=>{
391#							fcidrs=>\@cidrs,
392#							},
393#					 }
394#		  );
395#}
396
397#
398# Handle the ports search.
399#
400if ( defined( $ports_string ) ){
401	my @ports=split(/\,/, $ports_string);
402	push( @filters, {
403					 type=>'Ports',
404					 invert=>$ports_invert,
405					 args=>{
406							ports=>\@ports,
407							},
408					 }
409		 );
410}
411
412#
413# Handle the regex PTR searches
414#
415if ( defined( $ptrrs_string ) ){
416	my @ptrs=split(/\,/, $ptrrs_string);
417	push( @filters, {
418					 type=>'RegexPTR',
419					 invert=>$ptrrs_invert,
420					 args=>{
421							ptrs=>\@ptrs,
422							},
423					 }
424		 );
425}
426
427#
428# Handle the regex local PTR searches
429#
430if ( defined( $lptrrs_string ) ){
431	my @ptrs=split(/\,/, $lptrrs_string);
432	push( @filters, {
433					 type=>'RegexPTR',
434					 invert=>$lptrrs_invert,
435					 args=>{
436							lptrs=>\@ptrs,
437							},
438					 }
439		 );
440}
441
442#
443# Handle the regex remote PTR searches
444#
445if ( defined( $rptrrs_string ) ){
446	my @ptrs=split(/\,/, $rptrrs_string);
447	push( @filters, {
448					 type=>'RegexPTR',
449					 invert=>$rptrrs_invert,
450					 args=>{
451							fptrs=>\@ptrs,
452							},
453					 }
454		 );
455
456}
457
458#
459# Handle the ptrs searches
460#
461if ( defined( $ptrs_string ) ){
462	my @ptrs=split(/\,/, $ptrs_string);
463	push( @filters, {
464					 type=>'PTR',
465					 invert=>$rptrs_invert,
466					 args=>{
467							ptrs=>\@ptrs,
468							},
469					 }
470		 );
471}
472
473#
474# Handle the remote ptrs searches
475#
476if ( defined( $rptrs_string ) ){
477	my @ptrs=split(/\,/, $rptrs_string);
478	push( @filters, {
479					 type=>'PTR',
480					 invert=>$rptrs_invert,
481					 args=>{
482							fptrs=>\@ptrs,
483							},
484					 }
485		 );
486}
487
488#
489# Handle the local ptrs searches
490#
491if ( defined( $lptrs_string ) ){
492	my @ptrs=split(/\,/, $lptrs_string);
493	push( @filters, {
494					 type=>'PTR',
495					 invert=>$lptrs_invert,
496					 args=>{
497							lptrs=>\@ptrs,
498							},
499					 }
500		 );
501}
502
503#
504# Handle the PID searches
505#
506if ( defined( $pids_string ) ){
507	my @pids=split(/\,/, $pids_string);
508	push( @filters, {
509					 type=>'PID',
510					 invert=>$pids_invert,
511					 args=>{
512							pids=>\@pids,
513							},
514					 }
515		 );
516}
517
518#
519# Handle the command searches
520#
521if ( defined( $commands_string ) ){
522	my @commands=split(/\,/, $commands_string);
523	push( @filters, {
524					 type=>'Command',
525					 invert=>$commands_invert,
526					 args=>{
527							commands=>\@commands,
528							},
529					 }
530		 );
531}
532
533#
534# Handle the wait channel searches
535#
536if ( defined( $wchan_string ) ){
537	my @wchans=split(/\,/, $wchan_string);
538	push( @filters, {
539					 type=>'WChan',
540					 invert=>$wchan_invert,
541					 args=>{
542							wchans=>\@wchans,
543							},
544					 }
545		 );
546}
547
548#
549# Handle the pctcpu searches
550#
551if ( defined( $cpu_string ) ){
552	my @cpus=split(/\,/, $cpu_string);
553	push( @filters, {
554					 type=>'PctCPU',
555					 invert=>$cpu_invert,
556					 args=>{
557							pctcpus=>\@cpus,
558							},
559					 }
560		 );
561}
562
563#
564# Handle the pctmem searches
565#
566if ( defined( $mem_string ) ){
567	my @mems=split(/\,/, $mem_string);
568	push( @filters, {
569					 type=>'PctMem',
570					 invert=>$mem_invert,
571					 args=>{
572							pctmems=>\@mems,
573							},
574					 }
575		 );
576}
577
578# handle the -t -u options
579# only add a filter if one is specified...
580# adding both is just pointless
581if (
582	( ! $tcp ) &&
583	$udp
584	){
585	push( @filters, {
586					 type=>'Protos',
587					 invert=>0,
588					 args=>{
589							protos=>[ 'udp4', 'udp6' ],
590							}
591					 },
592		 );
593}elsif(
594	   $tcp &&
595	   ( ! $udp )
596	   ){
597	push( @filters, {
598					 type=>'Protos',
599					 invert=>0,
600					 args=>{
601							protos=>[ 'tcp4', 'tcp6' ],
602							}
603					 }
604		 );
605}
606
607if ( $no_use_ptr ){
608	$ptr=0;
609}
610
611# XOR the -i if needed
612if ( defined( $ENV{NCNETSTAT_invert} ) ){
613	$invert= $invert ^ $ENV{NCNETSTAT_invert};
614}
615# XOR the -n value if needed
616if ( defined( $ENV{NCNETSTAT_ptr} ) ){
617	$ptr = $ptr ^ $ENV{NCNETSTAT_ptr};
618}
619# same for the no color
620if ( defined( $ENV{NO_COLOR} ) ){
621	$no_color = $no_color ^ 1;
622}
623# disable the color if requested
624if ( $no_color ){
625	$ENV{ANSI_COLORS_DISABLED}=1;
626}
627# set C if Cl is set
628if ( $command_long && ! $command ){
629	$command=1;
630}
631
632#dump the filters if asked
633if ($dump) {
634	use Data::Dumper;
635	print Dumper( \@filters );
636	exit;
637}
638
639my $ncnetstat=Net::Connection::ncnetstat->new(
640											  {
641											   ptr=>$ptr,
642											   command=>$command,
643											   command_long=>$command_long,
644											   wchan=>$wchan_show,
645											   pct=>$pct_show,
646											   sorter=>{
647														invert=>$invert,
648														type=>$sort,
649														},
650											   match=>{
651													   checks=>\@filters,
652													   }
653											   }
654											  );
655print $ncnetstat->run;
656
657=head1 NAME
658
659ncnetstat - a netstat like utility that supports color and searching
660
661=head1 SYNOPSIS
662
663ncnetstat [B<-a>] [B<--drp>] [B<-l>] [B<-n>] [B<--nc>] [B<-S <sort>>] [B<-t>] [B<-u>]
664[B<-c <CIDRs>>] [B<--ci -p <ports>>] [B<--pi>] [B<-P <protocols>>] [B<--Pi>]
665[B<--ptr <PTRs>>] [B<--ptri>] [B<--lptr <PTRs>>] [B<--lptri>] [B<--rptr <PTRs>>] [B<--rptri>]
666[B<-s <states>>] [B<--si>] ...
667
668=head1 FLAGS
669
670=head2 -a
671
672Show all connections.
673
674=head2 -c <CIDRs>
675
676A comma seperated list of CIDRs to search for.
677
678=head2 --ci
679
680Invert the CIDR search.
681
682=head2 -C
683
684Show the command to the first space.
685
686=head2 --Cl
687
688Show the whole command.
689
690=head2 --cmd <cmds>
691
692A comma seperated list of commands to search for.
693
694=head2 --cmdi
695
696Invert the command search.
697
698=head2 --cpu <pct>
699
700Show connections belonging to procs matching this CPU usage percent.
701
702=head2--cpui
703
704Invert the CPU search.
705
706=head2 --drp
707
708Don't resolve port names.
709
710=head2 -i
711
712Invert the sort.
713
714=head2 -l
715
716Show the listening ports.
717
718=head2 --mem <pct>
719
720Show connections belonging to procs matching this memory usage percent.
721
722
723=head2 --memi
724
725Invert the memory usage search.
726
727=head2 -n
728
729Don't resolve the PTRs.
730
731=head2 --nc
732
733Don't use colors.
734
735=head2 -p <ports>
736
737A comma seperated list of ports to search for.
738
739=head2 --pct
740
741Show memory and CPU usage of the process that has the connection.
742
743=head2 --pi
744
745Invert the port search.
746
747=head2 -P <protocols>
748
749A comma seperated list of protocols to search for.
750
751=head2 --Pi
752
753Invert your protocol search.
754
755=head2 --pid <pids>
756
757A comma separated list of PIDs to search for.
758
759=head2 --pidi
760
761Invert the pid search.
762
763=head2 --ptr <PTRs>
764
765A comma seperated list of PTRs to search for.
766
767=head2 --ptri
768
769Invert the PTR search.
770
771=head2 --ptrr <rgx>
772
773A comma seperated list of regex to use for a PTR search.
774
775=head2 --ptrri
776
777Invert the RegexPTR search.
778
779=head2 --lptr <PTRs>
780
781A comma seperated list of local PTRs to search for.
782
783=head2 --lptri
784
785Invert the local PTR search.
786
787=head2 --lptrr <rgx>
788
789A comma seperated list of regex to use for a local PTR search.
790
791=head2 --lptrri
792
793Invert the local RegexPTR search.
794
795=head2 --rptr <PTRs>
796
797A comma seperated list of remote PTRs to search for.
798
799=head2 --rptri
800
801Invert the remote PTR search.
802
803=head2 --rptr <PTRs>
804
805A comma seperated list of remote PTRs to search for.
806
807=head2 --rptri
808
809Invert the remote PTR search.
810
811=head2 -s <states>
812
813A comma seperated list of states to search for.
814
815=head2 --si
816
817Invert the state search.
818
819=head2 -S <sort>
820
821The L<Net::Connection::Sort> to use.
822
823The default available sort methods are as below.
824
825    host_f   foreign host
826    host_fl  foreign host, local host *default*
827    host_l   local host
828    host_lf  local host, foreign host
829    pid      process ID
830    port_f   foreign port, numerically
831    port_fa  foreign port, alphabetically
832    port_l   local port, numerically
833    port_la  local port, alphabetically
834    proto    protocol
835    ptr_f    foreign PTR
836    ptr_l    local PTR
837    state    state
838    uid      user ID
839    user     username
840
841=head2 -t
842
843Show only TCP connections.
844
845=head2 -u
846
847Show only UDP connections.
848
849=head2 -U <users>
850
851A comma seperated list of usernames to search for.
852
853=head2 --Ui
854
855Invert the username search.
856
857=head2 --uid <uids>
858
859A comma separated list of UIDs to search for.
860
861=head2 --uidi
862
863Invert the UID search.
864
865=head2 -W
866
867Show the wait channel.
868
869=head2 -w <rgx>
870
871A comma separated list of regexp to use for matching wchan values.
872
873=head2 --wi
874
875Invert the wchan search
876
877=head1 PID/UID/CPU/Mem EQUALITIES
878
879For some searches, the equalities below can be used, by
880directly prepending them to the number.
881
882    <
883    <=
884    >
885    >=
886
887So if you wanted to find every connection from a UID greater than 1000, would
888do '--uid \>1000'.
889
890=head1 ENVIRONMENT VARIABLES
891
892=head2 NCNETSTAT_invert
893
894This is either 0 or 1. If defined it will be used for XORing the -i flag.
895
896    export CNETSTAT_invert=1
897    # run ncnetstat inverted
898    ncnetstat
899    # run it non-inverted, the opposite of what the -i flag normally is
900    ncnetstat -i
901
902=head2 NCNETSTAT_sort
903
904Sets the default sort method. -S overrides this.
905
906=head2 NO_COLOR
907
908If this is set, The output will not be colorized. If this is set, the --nc
909flag is also inverted.
910
911=head2 RES_NAMESERVERS
912
913A space-separated list of nameservers to query used by L<Net::DNS::Resolver>.
914
915There are a few more possible ones, but this is the most useful one and that documentation
916really belongs to that module.
917
918=head2 ncnetstat_C
919
920Used to xor the -C switch.
921
922Set to either 0 or 1, boolean, for setting the default.
923
924=head2 ncnetstat_Cl
925
926Used to xor the --Cl switch.
927
928Set to either 0 or 1, boolean, for setting the default.
929
930=head2 ncnetstat_W
931
932Used to xor the -W switch.
933
934Set to either 0 or 1, boolean, for setting the default.
935
936=head2 ncnetstat_pct
937
938Used to xor the --pct switch.
939
940Set to either 0 or 1, boolean, for setting the default.
941
942=head1 EXAMPLES
943
944    ncnetstat -s established,time_wait
945
946Return a list of connection that are in the established or time_wait state.
947
948    ncnetstat -c ::/0
949
950Return a list of all IPv6 addresses.
951
952    ncnetstat -c ::1/128,127.0.0.1/32
953
954Return all connections to localhost.
955
956    ncnetstat -c 192.168.15.2/32 -l
957
958Display all connections listening explicitly on 192.168.15.2.
959
960    ncnetstat -S host_f -i
961
962Sort the connections by the foreign host and invert the results.
963
964    ncnetstat -c 10.0.0.0/24 --ci
965
966Show connections that are either not locally or remotely part of the
96710.0.0.0/24 subnet.
968
969    ncnetstat --ptr foo.bar
970
971Find connections to/from IPs that have a PTR record of foo.bar.
972
973    ncnetstat --ptr foo.bar --ptri
974
975Find connections to/from IPs that do not have a PTR record of foo.bar.
976
977    ncnetstat -n --uid '>1000' --Cl
978
979Show every connection by a user with a UID greater than 1000, do not resolve
980PTR info and print the whole command.
981
982    ncnetstat -U www -p 80,443 --pi
983
984Show every connecttion by the user www that is not a HTTP or HTTPS connection.
985
986   ncnetstat --cpu '>5' --Cl --pct -W
987
988Search for connections from procs using more than 5% of the CPU time. Show memory
989and CPU usage as well whole command and wait channel.
990
991=cut
992