*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
+//config:config NETSTAT
+//config: bool "netstat (10 kb)"
+//config: default y
+//config: select PLATFORM_LINUX
+//config: help
+//config: netstat prints information about the Linux networking subsystem.
+//config:
+//config:config FEATURE_NETSTAT_WIDE
+//config: bool "Enable wide output"
+//config: default y
+//config: depends on NETSTAT
+//config: help
+//config: Add support for wide columns. Useful when displaying IPv6 addresses
+//config: (-W option).
+//config:
+//config:config FEATURE_NETSTAT_PRG
+//config: bool "Enable PID/Program name output"
+//config: default y
+//config: depends on NETSTAT
+//config: help
+//config: Add support for -p flag to print out PID and program name.
+//config: +700 bytes of code.
+
+//applet:IF_NETSTAT(APPLET(netstat, BB_DIR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_NETSTAT) += netstat.o
#include "libbb.h"
#include "inet_common.h"
//usage: "[-"IF_ROUTE("r")"al] [-tuwx] [-en"IF_FEATURE_NETSTAT_WIDE("W")IF_FEATURE_NETSTAT_PRG("p")"]"
//usage:#define netstat_full_usage "\n\n"
//usage: "Display networking information\n"
-//usage: "\nOptions:"
//usage: IF_ROUTE(
//usage: "\n -r Routing table"
//usage: )
#define ADDR_NORMAL_WIDTH 23
/* When there are IPv6 connections the IPv6 addresses will be
* truncated to none-recognition. The '-W' option makes the
- * address columns wide enough to accomodate for longest possible
+ * address columns wide enough to accommodate for longest possible
* IPv6 addresses, i.e. addresses of the form
* xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd
*/
#define ADDR_WIDE 51 /* INET6_ADDRSTRLEN + 5 for the port number */
#if ENABLE_FEATURE_NETSTAT_WIDE
-# define FMT_NET_CONN_DATA "%s %6ld %6ld %-*s %-*s %-12s"
+# define FMT_NET_CONN_DATA "%s %6lu %6lu %-*s %-*s %-12s"
# define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-*s %-*s State %s\n"
#else
-# define FMT_NET_CONN_DATA "%s %6ld %6ld %-23s %-23s %-12s"
+# define FMT_NET_CONN_DATA "%s %6lu %6lu %-23s %-23s %-12s"
# define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-23s %-23s State %s\n"
#endif
#define PRG_HASH_SIZE 211
struct globals {
- smallint flags;
+ smalluint flags;
#if ENABLE_FEATURE_NETSTAT_PRG
smallint prg_cache_loaded;
struct prg_node *prg_hash[PRG_HASH_SIZE];
for (pnp = prg_hash + hi; (pn = *pnp) != NULL; pnp = &pn->next) {
if (pn->inode == inode) {
/* Some warning should be appropriate here
- as we got multiple processes for one i-node */
+ * as we got multiple processes for one i-node */
return;
}
}
{
long inode = -1;
- if (strncmp(lname, "socket:[", sizeof("socket:[")-1) == 0) {
+ if (is_prefixed_with(lname, "socket:[")) {
/* "socket:[12345]", extract the "12345" as inode */
inode = bb_strtoul(lname + sizeof("socket:[")-1, (char**)&lname, 0);
if (*lname != ']')
inode = -1;
- } else if (strncmp(lname, "[0000]:", sizeof("[0000]:")-1) == 0) {
+ } else if (is_prefixed_with(lname, "[0000]:")) {
/* "[0000]:12345", extract the "12345" as inode */
inode = bb_strtoul(lname + sizeof("[0000]:")-1, NULL, 0);
if (errno) /* not NUL terminated? */
return;
if (prg_cache_loaded == 1)
- bb_error_msg("can't scan /proc - are you root?");
+ bb_simple_error_msg("can't scan /proc - are you root?");
else
- bb_error_msg("showing only processes with your user ID");
+ bb_simple_error_msg("showing only processes with your user ID");
}
#else
/* Code which used "*" for INADDR_ANY is removed: it's ambiguous
* in IPv6, while "0.0.0.0" is not. */
- host = numeric ? xmalloc_sockaddr2dotted_noport(addr)
- : xmalloc_sockaddr2host_noport(addr);
+ host = NULL;
+ if (!numeric)
+ host = xmalloc_sockaddr2host_noport(addr);
+ if (!host)
+ host = xmalloc_sockaddr2dotted_noport(addr);
host_port = xasprintf("%s:%s", host, get_sname(htons(port), proto, numeric));
free(host);
"%*d: %32[0-9A-Fa-f]:%X "
"%32[0-9A-Fa-f]:%X %X "
"%lX:%lX %*X:%*X "
- "%*X %d %*d %ld ",
+ "%*X %d %*d %lu ",
local_addr, ¶m->local_port,
rem_addr, ¶m->rem_port, ¶m->state,
¶m->txq, ¶m->rxq,
strcat(ss_flags, "N ");
strcat(ss_flags, "]");
- printf("%-5s %-6ld %-11s %-10s %-13s %6lu ",
+ printf("%-5s %-6lu %-11s %-10s %-13s %6lu ",
ss_proto, refcnt, ss_flags, ss_type, ss_state, inode
);
/* TODO: currently we stop at first NUL byte. Is it a problem? */
line += path_ofs;
- *strchrnul(line, '\n') = '\0';
+ chomp(line);
while (*line)
fputc_printable(*line++, stdout);
bb_putchar('\n');
flags |= opt;
}
if (flags & (NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW)) {
- printf("Active Internet connections "); /* xxx */
+ printf("Active Internet connections "); /* xxx */
if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) == (NETSTAT_LISTENING|NETSTAT_CONNECTED))
printf("(servers and established)");