3 # Copyright (c) 1999 Dag-Erling Coïdan Smørgrav
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer
11 # in this position and unchanged.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 # 3. The name of the author may not be used to endorse or promote products
16 # derived from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 # $FreeBSD: src/usr.bin/sockstat/sockstat.pl,v 1.6.2.6 2003/05/05 06:44:26 murray Exp $
37 my $unknown = [ "?", "?", "?", "?", "?", "?", "?", "?", "?" ];
39 my $inet_fmt = "%-8.8s %-8.8s %5.5s %4.4s %-6.6s %-21.21s %-21.21s\n";
40 my $unix_fmt = "%-8.8s %-8.8s %5.5s %4.4s %-6.6s %-43.43s\n";
43 # Gather information about sockets
49 my $line; # Input line
53 if (!defined($pid = open(PIPE, "-|"))) {
54 die("open(netstat): $!\n");
56 exec("/usr/bin/netstat", "-AanW");
57 die("exec(netstat): $!\n");
59 while ($line = <PIPE>) {
60 next unless ($line =~ m/^[0-9a-f]{8} /) || ($line =~ m/^[0-9a-f]{16} /);
62 @fields = split(' ', $line);
63 $netstat{$fields[0]} = [ @fields ];
66 or die("close(netstat): $!\n");
69 if (!defined($pid = open(PIPE, "-|"))) {
70 die("open(fstat): $!\n");
72 exec("/usr/bin/fstat");
73 die("exec(fstat): $!\n");
75 while ($line = <PIPE>) {
77 @fields = split(' ', $line);
78 next if ($fields[4] eq "-");
79 push(@{$fstat{$fields[4]}}, [ @fields ]);
82 or die("close(fstat): $!\n");
86 # Replace the last dot in an "address.port" string with a colon
89 my $addr = shift; # Address
91 $addr =~ s/^(.*)\.([^\.]*)$/$1:$2/;
96 # Print information about Internet sockets
99 my $af = shift; # Address family
100 my $conn = shift || 0; # Show connected sockets
101 my $listen = shift || 0; # Show listen sockets
103 my $fsd; # Fstat data
104 my $nsd; # Netstat data
106 printf($inet_fmt, "USER", "COMMAND", "PID", "FD",
107 "PROTO", "LOCAL ADDRESS", "FOREIGN ADDRESS");
108 foreach $fsd (@{$fstat{$af}}) {
109 next unless defined($fsd->[7]);
110 $nsd = $netstat{$fsd->[7]} || $unknown;
111 next if (!$conn && $nsd->[5] ne '*.*');
112 next if (!$listen && $nsd->[5] eq '*.*');
113 printf($inet_fmt, $fsd->[0], $fsd->[1], $fsd->[2],
114 substr($fsd->[3], 0, -1),
115 $nsd->[1], addr($nsd->[4]), addr($nsd->[5]));
121 # Print information about Unix domain sockets
124 my $conn = shift || 0; # Show connected sockets
125 my $listen = shift || 0; # Show listen sockets
127 my %endpoint; # Mad PCB to process/fd
128 my $fsd; # Fstat data
129 my $nsd; # Netstat data
131 foreach $fsd (@{$fstat{"local"}}) {
132 $endpoint{$fsd->[6]} = "$fsd->[1]\[$fsd->[2]\]:" .
133 substr($fsd->[3], 0, -1);
135 printf($unix_fmt, "USER", "COMMAND", "PID", "FD", "PROTO", "ADDRESS");
136 foreach $fsd (@{$fstat{"local"}}) {
137 next unless defined($fsd->[6]);
138 next if (!$conn && defined($fsd->[8]));
139 next if (!$listen && !defined($fsd->[8]));
140 $nsd = $netstat{$fsd->[6]} || $unknown;
141 printf($unix_fmt, $fsd->[0], $fsd->[1], $fsd->[2],
142 substr($fsd->[3], 0, -1), $fsd->[5],
143 $nsd->[8] || (($fsd->[8] && $endpoint{$fsd->[8]}) ? $endpoint{$fsd->[8]} : "(none)"));
149 # Print usage message and exit
152 print(STDERR "Usage: sockstat [-46clu]\n");
157 my %opts; # Command-line options
159 getopts("46clu", \%opts)
164 if (!$opts{'4'} && !$opts{'6'} && !$opts{'u'}) {
165 $opts{'4'} = $opts{'6'} = $opts{'u'} = 1;
167 if (!$opts{'c'} && !$opts{'l'}) {
168 $opts{'c'} = $opts{'l'} = 1;
171 print_inet("internet", $opts{'c'}, $opts{'l'});
174 print_inet("internet6", $opts{'c'}, $opts{'l'});
177 print_unix($opts{'c'}, $opts{'l'});