diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-27 12:10:07 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-27 12:10:07 +0000 |
commit | 6e69e4237d8f43232afd0dc207275f27c08039ed (patch) | |
tree | d2c3e28157fface75749fa6af53a23c4d85ba4c8 /networking | |
parent | 94d03f0da0809784b398585cd0d7669b77a475c9 (diff) | |
download | busybox-w32-6e69e4237d8f43232afd0dc207275f27c08039ed.tar.gz busybox-w32-6e69e4237d8f43232afd0dc207275f27c08039ed.tar.bz2 busybox-w32-6e69e4237d8f43232afd0dc207275f27c08039ed.zip |
netstat: optional -p support by L. Gabriel Somlo <somlo AT cmu.edu>
Without FEATURE_NETSTAT_PRG:
function old new delta
recursive_action 416 425 +9
tcp_do_one 420 428 +8
udp_do_one 492 499 +7
raw_do_one 472 479 +7
expand 1697 1701 +4
netstat_main 489 492 +3
unix_do_one 486 488 +2
flags 1 - -1
qgravechar 109 106 -3
net_conn_line 4 - -4
bbunpack 391 383 -8
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 7/2 up/down: 40/-16) Total: 24 bytes
With FEATURE_NETSTAT_PRG:
file_act - 213 +213
dir_act - 192 +192
netstat_main 489 601 +112
prg_cache_get - 50 +50
tcp_do_one 420 462 +42
udp_do_one 492 533 +41
raw_do_one 472 513 +41
unix_do_one 486 519 +33
recursive_action 416 425 +9
expand 1697 1701 +4
flags 1 - -1
qgravechar 109 106 -3
net_conn_line 4 - -4
bbunpack 391 383 -8
packed_usage 24586 24572 -14
------------------------------------------------------------------------------
(add/remove: 3/2 grow/shrink: 7/3 up/down: 737/-30) Total: 707 bytes
Diffstat (limited to 'networking')
-rw-r--r-- | networking/Config.in | 8 | ||||
-rw-r--r-- | networking/netstat.c | 282 |
2 files changed, 269 insertions, 21 deletions
diff --git a/networking/Config.in b/networking/Config.in index 5f38062c6..91f172997 100644 --- a/networking/Config.in +++ b/networking/Config.in | |||
@@ -633,6 +633,14 @@ config FEATURE_NETSTAT_WIDE | |||
633 | Add support for wide columns. Useful when displaying IPv6 addresses | 633 | Add support for wide columns. Useful when displaying IPv6 addresses |
634 | (-W option). | 634 | (-W option). |
635 | 635 | ||
636 | config FEATURE_NETSTAT_PRG | ||
637 | bool "Enable PID/Program name output" | ||
638 | default n | ||
639 | depends on NETSTAT | ||
640 | help | ||
641 | Add support for -p flag to print out PID and program name. | ||
642 | +700 bytes of code. | ||
643 | |||
636 | config NSLOOKUP | 644 | config NSLOOKUP |
637 | bool "nslookup" | 645 | bool "nslookup" |
638 | default n | 646 | default n |
diff --git a/networking/netstat.c b/networking/netstat.c index 46510acc1..0c0b69afe 100644 --- a/networking/netstat.c +++ b/networking/netstat.c | |||
@@ -8,18 +8,37 @@ | |||
8 | * 2002-04-20 | 8 | * 2002-04-20 |
9 | * IPV6 support added by Bart Visscher <magick@linux-fan.com> | 9 | * IPV6 support added by Bart Visscher <magick@linux-fan.com> |
10 | * | 10 | * |
11 | * 2008-07-10 | ||
12 | * optional '-p' flag support ported from net-tools by G. Somlo <somlo@cmu.edu> | ||
13 | * | ||
11 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 14 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
12 | */ | 15 | */ |
13 | 16 | ||
14 | #include "libbb.h" | 17 | #include "libbb.h" |
15 | #include "inet_common.h" | 18 | #include "inet_common.h" |
16 | 19 | ||
20 | #define NETSTAT_OPTS "laentuwx" \ | ||
21 | USE_ROUTE( "r") \ | ||
22 | USE_FEATURE_NETSTAT_WIDE("W") \ | ||
23 | USE_FEATURE_NETSTAT_PRG( "p") | ||
24 | |||
17 | enum { | 25 | enum { |
18 | OPT_extended = 0x4, | 26 | OPTBIT_KEEP_OLD = 7, |
19 | OPT_showroute = 0x100, | 27 | USE_ROUTE( OPTBIT_ROUTE,) |
20 | OPT_widedisplay = 0x200 * ENABLE_FEATURE_NETSTAT_WIDE, | 28 | USE_FEATURE_NETSTAT_WIDE(OPTBIT_WIDE ,) |
29 | USE_FEATURE_NETSTAT_PRG( OPTBIT_PRG ,) | ||
30 | OPT_sock_listen = 1 << 0, // l | ||
31 | OPT_sock_all = 1 << 1, // a | ||
32 | OPT_extended = 1 << 2, // e | ||
33 | OPT_noresolve = 1 << 3, // n | ||
34 | OPT_sock_tcp = 1 << 4, // t | ||
35 | OPT_sock_udp = 1 << 5, // u | ||
36 | OPT_sock_raw = 1 << 6, // w | ||
37 | OPT_sock_unix = 1 << 7, // x | ||
38 | OPT_route = USE_ROUTE( (1 << OPTBIT_ROUTE)) + 0, // r | ||
39 | OPT_wide = USE_FEATURE_NETSTAT_WIDE((1 << OPTBIT_WIDE )) + 0, // W | ||
40 | OPT_prg = USE_FEATURE_NETSTAT_PRG( (1 << OPTBIT_PRG )) + 0, // p | ||
21 | }; | 41 | }; |
22 | # define NETSTAT_OPTS "laentuwxr"USE_FEATURE_NETSTAT_WIDE("W") | ||
23 | 42 | ||
24 | #define NETSTAT_CONNECTED 0x01 | 43 | #define NETSTAT_CONNECTED 0x01 |
25 | #define NETSTAT_LISTENING 0x02 | 44 | #define NETSTAT_LISTENING 0x02 |
@@ -31,7 +50,6 @@ enum { | |||
31 | #define NETSTAT_UNIX 0x80 | 50 | #define NETSTAT_UNIX 0x80 |
32 | #define NETSTAT_ALLPROTO (NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW|NETSTAT_UNIX) | 51 | #define NETSTAT_ALLPROTO (NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW|NETSTAT_UNIX) |
33 | 52 | ||
34 | static smallint flags = NETSTAT_CONNECTED | NETSTAT_ALLPROTO; | ||
35 | 53 | ||
36 | enum { | 54 | enum { |
37 | TCP_ESTABLISHED = 1, | 55 | TCP_ESTABLISHED = 1, |
@@ -44,7 +62,7 @@ enum { | |||
44 | TCP_CLOSE_WAIT, | 62 | TCP_CLOSE_WAIT, |
45 | TCP_LAST_ACK, | 63 | TCP_LAST_ACK, |
46 | TCP_LISTEN, | 64 | TCP_LISTEN, |
47 | TCP_CLOSING /* now a valid state */ | 65 | TCP_CLOSING, /* now a valid state */ |
48 | }; | 66 | }; |
49 | 67 | ||
50 | static const char *const tcp_state[] = { | 68 | static const char *const tcp_state[] = { |
@@ -76,8 +94,8 @@ typedef enum { | |||
76 | 94 | ||
77 | /* Standard printout size */ | 95 | /* Standard printout size */ |
78 | #define PRINT_IP_MAX_SIZE 23 | 96 | #define PRINT_IP_MAX_SIZE 23 |
79 | #define PRINT_NET_CONN "%s %6ld %6ld %-23s %-23s %-12s\n" | 97 | #define PRINT_NET_CONN "%s %6ld %6ld %-23s %-23s %-12s" |
80 | #define PRINT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-23s %-23s State\n" | 98 | #define PRINT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-23s %-23s State " |
81 | 99 | ||
82 | /* When there are IPv6 connections the IPv6 addresses will be | 100 | /* When there are IPv6 connections the IPv6 addresses will be |
83 | * truncated to none-recognition. The '-W' option makes the | 101 | * truncated to none-recognition. The '-W' option makes the |
@@ -86,10 +104,201 @@ typedef enum { | |||
86 | * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd | 104 | * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd |
87 | */ | 105 | */ |
88 | #define PRINT_IP_MAX_SIZE_WIDE 51 /* INET6_ADDRSTRLEN + 5 for the port number */ | 106 | #define PRINT_IP_MAX_SIZE_WIDE 51 /* INET6_ADDRSTRLEN + 5 for the port number */ |
89 | #define PRINT_NET_CONN_WIDE "%s %6ld %6ld %-51s %-51s %-12s\n" | 107 | #define PRINT_NET_CONN_WIDE "%s %6ld %6ld %-51s %-51s %-12s" |
90 | #define PRINT_NET_CONN_HEADER_WIDE "\nProto Recv-Q Send-Q %-51s %-51s State\n" | 108 | #define PRINT_NET_CONN_HEADER_WIDE "\nProto Recv-Q Send-Q %-51s %-51s State " |
109 | |||
110 | |||
111 | #define PROGNAME_WIDTH 20 | ||
112 | #define PROGNAME_WIDTH_STR "20" | ||
113 | /* PROGNAME_WIDTH chars: 12345678901234567890 */ | ||
114 | #define PROGNAME_BANNER "PID/Program name " | ||
115 | |||
116 | struct prg_node { | ||
117 | struct prg_node *next; | ||
118 | long inode; | ||
119 | char name[PROGNAME_WIDTH]; | ||
120 | }; | ||
121 | |||
122 | #define PRG_HASH_SIZE 211 | ||
123 | |||
124 | |||
125 | struct globals { | ||
126 | const char *net_conn_line; | ||
127 | smallint flags; | ||
128 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
129 | smallint prg_cache_loaded; | ||
130 | struct prg_node *prg_hash[PRG_HASH_SIZE]; | ||
131 | #endif | ||
132 | }; | ||
133 | #define G (*ptr_to_globals) | ||
134 | #define flags (G.flags ) | ||
135 | #define net_conn_line (G.net_conn_line ) | ||
136 | #define prg_hash (G.prg_hash ) | ||
137 | #define prg_cache_loaded (G.prg_cache_loaded) | ||
138 | #define INIT_G() do { \ | ||
139 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | ||
140 | flags = NETSTAT_CONNECTED | NETSTAT_ALLPROTO; \ | ||
141 | net_conn_line = PRINT_NET_CONN; \ | ||
142 | } while (0) | ||
143 | |||
144 | |||
145 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
146 | |||
147 | /* Deliberately truncating long to unsigned *int* */ | ||
148 | #define PRG_HASHIT(x) ((unsigned)(x) % PRG_HASH_SIZE) | ||
149 | |||
150 | #define print_progname_banner() do { \ | ||
151 | if (option_mask32 & OPT_prg) printf(PROGNAME_BANNER); \ | ||
152 | } while (0) | ||
153 | |||
154 | static void prg_cache_add(long inode, char *name) | ||
155 | { | ||
156 | unsigned hi = PRG_HASHIT(inode); | ||
157 | struct prg_node **pnp, *pn; | ||
158 | |||
159 | prg_cache_loaded = 2; | ||
160 | for (pnp = prg_hash + hi; (pn = *pnp) != NULL; pnp = &pn->next) { | ||
161 | if (pn->inode == inode) { | ||
162 | /* Some warning should be appropriate here | ||
163 | as we got multiple processes for one i-node */ | ||
164 | return; | ||
165 | } | ||
166 | } | ||
167 | *pnp = xzalloc(sizeof(struct prg_node)); | ||
168 | pn = *pnp; | ||
169 | pn->inode = inode; | ||
170 | safe_strncpy(pn->name, name, PROGNAME_WIDTH); | ||
171 | } | ||
172 | |||
173 | static const char *prg_cache_get(long inode) | ||
174 | { | ||
175 | unsigned hi = PRG_HASHIT(inode); | ||
176 | struct prg_node *pn; | ||
177 | |||
178 | for (pn = prg_hash[hi]; pn; pn = pn->next) | ||
179 | if (pn->inode == inode) | ||
180 | return pn->name; | ||
181 | return "-"; | ||
182 | } | ||
183 | |||
184 | #if ENABLE_FEATURE_CLEAN_UP | ||
185 | static void prg_cache_clear(void) | ||
186 | { | ||
187 | struct prg_node **pnp, *pn; | ||
188 | |||
189 | for (pnp = prg_hash; pnp < prg_hash + PRG_HASH_SIZE; pnp++) { | ||
190 | while ((pn = *pnp) != NULL) { | ||
191 | *pnp = pn->next; | ||
192 | free(pn); | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | #else | ||
197 | #define prg_cache_clear() ((void)0) | ||
198 | #endif | ||
91 | 199 | ||
92 | static const char *net_conn_line = PRINT_NET_CONN; | 200 | static long extract_socket_inode(const char *lname) { |
201 | |||
202 | long inode = -1; | ||
203 | |||
204 | if (strncmp(lname, "socket:[", sizeof("socket:[")-1) == 0) { | ||
205 | /* "socket:[12345]", extract the "12345" as inode */ | ||
206 | inode = bb_strtol(lname + sizeof("socket:[")-1, (char**)&lname, 0); | ||
207 | if (*lname != ']') | ||
208 | inode = -1; | ||
209 | } else if (strncmp(lname, "[0000]:", sizeof("[0000]:")-1) == 0) { | ||
210 | /* "[0000]:12345", extract the "12345" as inode */ | ||
211 | inode = bb_strtol(lname + sizeof("[0000]:")-1, NULL, 0); | ||
212 | if (errno) /* not NUL terminated? */ | ||
213 | inode = -1; | ||
214 | } | ||
215 | |||
216 | #if 0 /* bb_strtol returns all-ones bit pattern on ERANGE anyway */ | ||
217 | if (errno == ERANGE) | ||
218 | inode = -1; | ||
219 | #endif | ||
220 | return inode; | ||
221 | } | ||
222 | |||
223 | static int FAST_FUNC file_act(const char *fileName, | ||
224 | struct stat *statbuf UNUSED_PARAM, | ||
225 | void *userData, | ||
226 | int depth UNUSED_PARAM) | ||
227 | { | ||
228 | char *linkname; | ||
229 | long inode; | ||
230 | |||
231 | linkname = xmalloc_readlink(fileName); | ||
232 | if (linkname != NULL) { | ||
233 | inode = extract_socket_inode(linkname); | ||
234 | free(linkname); | ||
235 | if (inode >= 0) | ||
236 | prg_cache_add(inode, (char *)userData); | ||
237 | } | ||
238 | return TRUE; | ||
239 | } | ||
240 | |||
241 | static int FAST_FUNC dir_act(const char *fileName, | ||
242 | struct stat *statbuf UNUSED_PARAM, | ||
243 | void *userData UNUSED_PARAM, | ||
244 | int depth) | ||
245 | { | ||
246 | const char *shortName; | ||
247 | char *p, *q; | ||
248 | char cmdline_buf[512]; | ||
249 | int i; | ||
250 | |||
251 | if (depth == 0) /* "/proc" itself */ | ||
252 | return TRUE; /* continue looking one level below /proc */ | ||
253 | |||
254 | shortName = fileName + sizeof("/proc/")-1; /* point after "/proc/" */ | ||
255 | if (!isdigit(shortName[0])) /* skip /proc entries whic aren't processes */ | ||
256 | return SKIP; | ||
257 | |||
258 | p = concat_path_file(fileName, "cmdline"); /* "/proc/PID/cmdline" */ | ||
259 | i = open_read_close(p, cmdline_buf, sizeof(cmdline_buf) - 1); | ||
260 | free(p); | ||
261 | if (i < 0) | ||
262 | return FALSE; | ||
263 | cmdline_buf[i] = '\0'; | ||
264 | q = concat_path_file(shortName, bb_basename(cmdline_buf)); /* "PID/argv0" */ | ||
265 | |||
266 | /* go through all files in /proc/PID/fd */ | ||
267 | p = concat_path_file(fileName, "fd"); | ||
268 | i = recursive_action(p, ACTION_RECURSE | ACTION_QUIET, | ||
269 | file_act, NULL, (void *)q, 0); | ||
270 | |||
271 | free(p); | ||
272 | free(q); | ||
273 | |||
274 | if (!i) | ||
275 | return FALSE; /* signal permissions error to caller */ | ||
276 | |||
277 | return SKIP; /* caller should not recurse further into this dir. */ | ||
278 | } | ||
279 | |||
280 | static void prg_cache_load(void) | ||
281 | { | ||
282 | int load_ok; | ||
283 | |||
284 | prg_cache_loaded = 1; | ||
285 | load_ok = recursive_action("/proc", ACTION_RECURSE | ACTION_QUIET, | ||
286 | NULL, dir_act, NULL, 0); | ||
287 | if (load_ok) | ||
288 | return; | ||
289 | |||
290 | if (prg_cache_loaded == 1) | ||
291 | bb_error_msg("can't scan /proc - are you root?"); | ||
292 | else | ||
293 | bb_error_msg("showing only processes with your user ID"); | ||
294 | } | ||
295 | |||
296 | #else | ||
297 | |||
298 | #define prg_cache_clear() ((void)0) | ||
299 | #define print_progname_banner() ((void)0) | ||
300 | |||
301 | #endif //ENABLE_FEATURE_NETSTAT_PRG | ||
93 | 302 | ||
94 | 303 | ||
95 | #if ENABLE_FEATURE_IPV6 | 304 | #if ENABLE_FEATURE_IPV6 |
@@ -195,6 +404,11 @@ static int tcp_do_one(int lnr, char *line) | |||
195 | "tcp", flags & NETSTAT_NUMERIC); | 404 | "tcp", flags & NETSTAT_NUMERIC); |
196 | printf(net_conn_line, | 405 | printf(net_conn_line, |
197 | "tcp", rxq, txq, l, r, tcp_state[state]); | 406 | "tcp", rxq, txq, l, r, tcp_state[state]); |
407 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
408 | if (option_mask32 & OPT_prg) | ||
409 | printf("%."PROGNAME_WIDTH_STR"s", prg_cache_get(inode)); | ||
410 | #endif | ||
411 | bb_putchar('\n'); | ||
198 | free(l); | 412 | free(l); |
199 | free(r); | 413 | free(r); |
200 | } | 414 | } |
@@ -276,6 +490,11 @@ static int udp_do_one(int lnr, char *line) | |||
276 | "udp", flags & NETSTAT_NUMERIC); | 490 | "udp", flags & NETSTAT_NUMERIC); |
277 | printf(net_conn_line, | 491 | printf(net_conn_line, |
278 | "udp", rxq, txq, l, r, state_str); | 492 | "udp", rxq, txq, l, r, state_str); |
493 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
494 | if (option_mask32 & OPT_prg) | ||
495 | printf("%."PROGNAME_WIDTH_STR"s", prg_cache_get(inode)); | ||
496 | #endif | ||
497 | bb_putchar('\n'); | ||
279 | free(l); | 498 | free(l); |
280 | free(r); | 499 | free(r); |
281 | } | 500 | } |
@@ -332,6 +551,11 @@ static int raw_do_one(int lnr, char *line) | |||
332 | "raw", flags & NETSTAT_NUMERIC); | 551 | "raw", flags & NETSTAT_NUMERIC); |
333 | printf(net_conn_line, | 552 | printf(net_conn_line, |
334 | "raw", rxq, txq, l, r, itoa(state)); | 553 | "raw", rxq, txq, l, r, itoa(state)); |
554 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
555 | if (option_mask32 & OPT_prg) | ||
556 | printf("%-"PROGNAME_WIDTH_STR"s", prg_cache_get(inode)); | ||
557 | #endif | ||
558 | bb_putchar('\n'); | ||
335 | free(l); | 559 | free(l); |
336 | free(r); | 560 | free(r); |
337 | } | 561 | } |
@@ -443,6 +667,11 @@ static int unix_do_one(int nr, char *line) | |||
443 | ss_proto, refcnt, ss_flags, ss_type, ss_state, inode | 667 | ss_proto, refcnt, ss_flags, ss_type, ss_state, inode |
444 | ); | 668 | ); |
445 | 669 | ||
670 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
671 | if (option_mask32 & OPT_prg) | ||
672 | printf("%-"PROGNAME_WIDTH_STR"s", prg_cache_get(inode)); | ||
673 | #endif | ||
674 | |||
446 | /* TODO: currently we stop at first NUL byte. Is it a problem? */ | 675 | /* TODO: currently we stop at first NUL byte. Is it a problem? */ |
447 | line += path_ofs; | 676 | line += path_ofs; |
448 | *strchrnul(line, '\n') = '\0'; | 677 | *strchrnul(line, '\n') = '\0'; |
@@ -497,6 +726,8 @@ int netstat_main(int argc UNUSED_PARAM, char **argv) | |||
497 | enum { inet = 1, inet6 = 0 }; | 726 | enum { inet = 1, inet6 = 0 }; |
498 | #endif | 727 | #endif |
499 | 728 | ||
729 | INIT_G(); | ||
730 | |||
500 | /* Option string must match NETSTAT_xxx constants */ | 731 | /* Option string must match NETSTAT_xxx constants */ |
501 | opt = getopt32(argv, NETSTAT_OPTS); | 732 | opt = getopt32(argv, NETSTAT_OPTS); |
502 | if (opt & 0x1) { // -l | 733 | if (opt & 0x1) { // -l |
@@ -510,7 +741,7 @@ int netstat_main(int argc UNUSED_PARAM, char **argv) | |||
510 | //if (opt & 0x20) // -u: NETSTAT_UDP | 741 | //if (opt & 0x20) // -u: NETSTAT_UDP |
511 | //if (opt & 0x40) // -w: NETSTAT_RAW | 742 | //if (opt & 0x40) // -w: NETSTAT_RAW |
512 | //if (opt & 0x80) // -x: NETSTAT_UNIX | 743 | //if (opt & 0x80) // -x: NETSTAT_UNIX |
513 | if (opt & OPT_showroute) { // -r | 744 | if (opt & OPT_route) { // -r |
514 | #if ENABLE_ROUTE | 745 | #if ENABLE_ROUTE |
515 | bb_displayroutes(flags & NETSTAT_NUMERIC, !(opt & OPT_extended)); | 746 | bb_displayroutes(flags & NETSTAT_NUMERIC, !(opt & OPT_extended)); |
516 | return 0; | 747 | return 0; |
@@ -518,11 +749,15 @@ int netstat_main(int argc UNUSED_PARAM, char **argv) | |||
518 | bb_show_usage(); | 749 | bb_show_usage(); |
519 | #endif | 750 | #endif |
520 | } | 751 | } |
521 | 752 | if (opt & OPT_wide) { // -W | |
522 | if (opt & OPT_widedisplay) { // -W | ||
523 | net_conn_line = PRINT_NET_CONN_WIDE; | 753 | net_conn_line = PRINT_NET_CONN_WIDE; |
524 | net_conn_line_header = PRINT_NET_CONN_HEADER_WIDE; | 754 | net_conn_line_header = PRINT_NET_CONN_HEADER_WIDE; |
525 | } | 755 | } |
756 | #if ENABLE_FEATURE_NETSTAT_PRG | ||
757 | if (opt & OPT_prg) { // -p | ||
758 | prg_cache_load(); | ||
759 | } | ||
760 | #endif | ||
526 | 761 | ||
527 | opt &= NETSTAT_ALLPROTO; | 762 | opt &= NETSTAT_ALLPROTO; |
528 | if (opt) { | 763 | if (opt) { |
@@ -539,23 +774,25 @@ int netstat_main(int argc UNUSED_PARAM, char **argv) | |||
539 | else | 774 | else |
540 | printf("(w/o servers)"); | 775 | printf("(w/o servers)"); |
541 | printf(net_conn_line_header, "Local Address", "Foreign Address"); | 776 | printf(net_conn_line_header, "Local Address", "Foreign Address"); |
777 | print_progname_banner(); | ||
778 | bb_putchar('\n'); | ||
542 | } | 779 | } |
543 | if (inet && flags & NETSTAT_TCP) | 780 | if (inet && (flags & NETSTAT_TCP)) |
544 | do_info(_PATH_PROCNET_TCP, "AF INET (tcp)", tcp_do_one); | 781 | do_info(_PATH_PROCNET_TCP, "AF INET (tcp)", tcp_do_one); |
545 | #if ENABLE_FEATURE_IPV6 | 782 | #if ENABLE_FEATURE_IPV6 |
546 | if (inet6 && flags & NETSTAT_TCP) | 783 | if (inet6 && (flags & NETSTAT_TCP)) |
547 | do_info(_PATH_PROCNET_TCP6, "AF INET6 (tcp)", tcp_do_one); | 784 | do_info(_PATH_PROCNET_TCP6, "AF INET6 (tcp)", tcp_do_one); |
548 | #endif | 785 | #endif |
549 | if (inet && flags & NETSTAT_UDP) | 786 | if (inet && (flags & NETSTAT_UDP)) |
550 | do_info(_PATH_PROCNET_UDP, "AF INET (udp)", udp_do_one); | 787 | do_info(_PATH_PROCNET_UDP, "AF INET (udp)", udp_do_one); |
551 | #if ENABLE_FEATURE_IPV6 | 788 | #if ENABLE_FEATURE_IPV6 |
552 | if (inet6 && flags & NETSTAT_UDP) | 789 | if (inet6 && (flags & NETSTAT_UDP)) |
553 | do_info(_PATH_PROCNET_UDP6, "AF INET6 (udp)", udp_do_one); | 790 | do_info(_PATH_PROCNET_UDP6, "AF INET6 (udp)", udp_do_one); |
554 | #endif | 791 | #endif |
555 | if (inet && flags & NETSTAT_RAW) | 792 | if (inet && (flags & NETSTAT_RAW)) |
556 | do_info(_PATH_PROCNET_RAW, "AF INET (raw)", raw_do_one); | 793 | do_info(_PATH_PROCNET_RAW, "AF INET (raw)", raw_do_one); |
557 | #if ENABLE_FEATURE_IPV6 | 794 | #if ENABLE_FEATURE_IPV6 |
558 | if (inet6 && flags & NETSTAT_RAW) | 795 | if (inet6 && (flags & NETSTAT_RAW)) |
559 | do_info(_PATH_PROCNET_RAW6, "AF INET6 (raw)", raw_do_one); | 796 | do_info(_PATH_PROCNET_RAW6, "AF INET6 (raw)", raw_do_one); |
560 | #endif | 797 | #endif |
561 | if (flags & NETSTAT_UNIX) { | 798 | if (flags & NETSTAT_UNIX) { |
@@ -566,8 +803,11 @@ int netstat_main(int argc UNUSED_PARAM, char **argv) | |||
566 | printf("(only servers)"); | 803 | printf("(only servers)"); |
567 | else | 804 | else |
568 | printf("(w/o servers)"); | 805 | printf("(w/o servers)"); |
569 | printf("\nProto RefCnt Flags Type State I-Node Path\n"); | 806 | printf("\nProto RefCnt Flags Type State I-Node "); |
807 | print_progname_banner(); | ||
808 | printf("Path\n"); | ||
570 | do_info(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one); | 809 | do_info(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one); |
571 | } | 810 | } |
811 | prg_cache_clear(); | ||
572 | return 0; | 812 | return 0; |
573 | } | 813 | } |