summaryrefslogtreecommitdiffstats
path: root/usr.bin/sockstat
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2000-10-07 14:10:37 +0000
committerdes <des@FreeBSD.org>2000-10-07 14:10:37 +0000
commit35a375ea90f83fec3c572aa2bc8c481bef86a9db (patch)
tree286f89ec54fc561cd7113c41ec5a9695a0703799 /usr.bin/sockstat
parent2f43c7014124bbdab8d84f8af679c287f2198aa9 (diff)
downloadFreeBSD-src-35a375ea90f83fec3c572aa2bc8c481bef86a9db.zip
FreeBSD-src-35a375ea90f83fec3c572aa2bc8c481bef86a9db.tar.gz
Total rewrite. This was actually the first non-trivial Perl script I ever
wrote, and as such was not very pretty. Changes that may cause problems for people who use sockstat in scripts: - sockstat(8) now displays Unix domain sockets in addition to IPv4 and IPv6 - the last period in local and foreign addresses is changed to a colon to make the port number easier to spot - IPv4 and IPv6 sockets are listed separately (IPv4 first, then IPv6, then Unix)
Diffstat (limited to 'usr.bin/sockstat')
-rw-r--r--usr.bin/sockstat/sockstat.pl155
1 files changed, 129 insertions, 26 deletions
diff --git a/usr.bin/sockstat/sockstat.pl b/usr.bin/sockstat/sockstat.pl
index 0ec2670..a6223ac 100644
--- a/usr.bin/sockstat/sockstat.pl
+++ b/usr.bin/sockstat/sockstat.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl5
+#!/usr/bin/perl -w
#-
# Copyright (c) 1999 Dag-Erling Coïdan Smørgrav
# All rights reserved.
@@ -29,37 +29,140 @@
# $FreeBSD$
#
-my (%proto, %myaddr, %hisaddr);
-my ($user, $cmd, $pid, $fd, $inet, $type, $proto, $sock, $laddr, $faddr);
+use strict;
+use Getopt::Std;
-print <<EOH;
-USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
-EOH
-format STDOUT =
-@<<<<<<< @<<<<<<< @>>>> @>>> @<<<<< @<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<
-$user, $cmd, $pid, $fd, $proto,$laddr, $faddr
-.
+my %netstat;
+my %fstat;
+my $unknown = [ "?", "?", "?", "?", "?", "?", "?", "?", "?" ];
-open NETSTAT, "/usr/bin/netstat -Aan |" or die "'netstat' failed: $!";
-<NETSTAT>; <NETSTAT>;
+my $inet_fmt = "%-8.8s %-8.8s %5.5s %4.4s %-6.6s %-21.21s %-21.21s\n";
+my $unix_fmt = "%-8.8s %-8.8s %5.5s %4.4s %-6.6s %-43.43s\n";
-while (<NETSTAT>) {
- my ($sock, $proto, $recvq, $sendq, $laddr, $faddr, $state) = split;
- ($proto{$sock}, $myaddr{$sock}, $hisaddr{$sock}) =
- ($proto, $laddr, $faddr);
+#
+# Gather information about sockets
+#
+sub gather() {
+
+ local *PIPE; # Pipe
+ my $pid; # Child PID
+ my $line; # Input line
+ my @fields; # Fields
+
+ # Netstat
+ if (!defined($pid = open(PIPE, "-|"))) {
+ die("open(netstat): $!\n");
+ } elsif ($pid == 0) {
+ exec("/usr/bin/netstat", "-Aan");
+ die("exec(netstat): $!\n");
+ }
+ while ($line = <PIPE>) {
+ next unless ($line =~ m/^[0-9a-f]{8} /);
+ chomp($line);
+ @fields = split(' ', $line);
+ $netstat{$fields[0]} = [ @fields ];
+ }
+ close(PIPE)
+ or die("close(netstat): $!\n");
+
+ # Fstat
+ if (!defined($pid = open(PIPE, "-|"))) {
+ die("open(fstat): $!\n");
+ } elsif ($pid == 0) {
+ exec("/usr/bin/fstat");
+ die("exec(fstat): $!\n");
+ }
+ while ($line = <PIPE>) {
+ chomp($line);
+ @fields = split(' ', $line);
+ next if ($fields[4] eq "-");
+ push(@{$fstat{$fields[4]}}, [ @fields ]);
+ }
+ close(PIPE)
+ or die("close(fstat): $!\n");
}
-close NETSTAT;
+#
+# Replace the last dot in an "address.port" string with a colon
+#
+sub addr($) {
+ my $addr = shift; # Address
-open FSTAT, "/usr/bin/fstat |" or die "'fstat' failed: $!\n";
+ $addr =~ s/^(.*)\.([^\.]*)$/$1:$2/;
+ return $addr;
+}
-while (<FSTAT>) {
- ($user, $cmd, $pid, $fd, $inet, $type, $proto, $sock) = split;
- chop $fd;
- next unless ($inet eq "internet") || ($inet eq "internet6") && ($type ne "raw");
- ($proto, $laddr, $faddr) =
- ($proto{$sock}, $myaddr{$sock}, $hisaddr{$sock});
- write STDOUT;
+#
+# Print information about Internet sockets
+#
+sub print_inet($) {
+ my $af = shift; # Address family
+
+ my $fsd; # Fstat data
+ my $nsd; # Netstat data
+
+ printf($inet_fmt, "USER", "COMMAND", "PID", "FD",
+ "PROTO", "LOCAL ADDRESS", "FOREIGN ADDRESS");
+ foreach $fsd (@{$fstat{$af}}) {
+ $nsd = $netstat{$fsd->[7]} || $unknown;
+ printf($inet_fmt, $fsd->[0], $fsd->[1], $fsd->[2],
+ substr($fsd->[3], 0, -1),
+ $nsd->[1], addr($nsd->[4]), addr($nsd->[5]));
+ }
+ print("\n");
}
-close FSTAT;
+#
+# Print information about Unix domain sockets
+#
+sub print_unix() {
+
+ my %endpoint; # Mad PCB to process/fd
+ my $fsd; # Fstat data
+ my $nsd; # Netstat data
+
+ foreach $fsd (@{$fstat{"local"}}) {
+ $endpoint{$fsd->[6]} = "$fsd->[1]\[$fsd->[2]\]:" .
+ substr($fsd->[3], 0, -1);
+ }
+ printf($unix_fmt, "USER", "COMMAND", "PID", "FD", "PROTO", "ADDRESS");
+ foreach $fsd (@{$fstat{"local"}}) {
+ $nsd = $netstat{$fsd->[6]} || $unknown;
+ printf($unix_fmt, $fsd->[0], $fsd->[1], $fsd->[2],
+ substr($fsd->[3], 0, -1), $fsd->[5],
+ $nsd->[8] || ($fsd->[8] ? $endpoint{$fsd->[8]} : "(none)"));
+ }
+ print("\n");
+}
+
+#
+# Print usage message and exit
+#
+sub usage() {
+ print(STDERR "Usage: sockstat [-46u]\n");
+ exit(1);
+}
+
+MAIN:{
+ my %opts; # Command-line options
+
+ getopts("46u", \%opts)
+ or usage();
+
+ gather();
+
+ if (!$opts{'4'} && !$opts{'6'} && !$opts{'u'}) {
+ $opts{'4'} = $opts{'6'} = $opts{'u'} = 1;
+ }
+ if ($opts{'4'}) {
+ print_inet("internet");
+ }
+ if ($opts{'6'}) {
+ print_inet("internet6");
+ }
+ if ($opts{'u'}) {
+ print_unix();
+ }
+
+ exit(0);
+}
OpenPOWER on IntegriCloud