aboutsummaryrefslogtreecommitdiff
path: root/networking/netstat.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-27 17:24:19 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-27 17:24:19 +0000
commit2c7a1fd6d4dbc77c64151e7ffe3f6aea5fada33a (patch)
treef69a932dc7a045cbcde271d8cabe0075c1ef7347 /networking/netstat.c
parentcf8b1ef8457a9a5c978dd8fc3a36fde3feb2bbfe (diff)
downloadbusybox-w32-2c7a1fd6d4dbc77c64151e7ffe3f6aea5fada33a.tar.gz
busybox-w32-2c7a1fd6d4dbc77c64151e7ffe3f6aea5fada33a.tar.bz2
busybox-w32-2c7a1fd6d4dbc77c64151e7ffe3f6aea5fada33a.zip
netstat: code shrink
function old new delta print_inet_line - 193 +193 scan_inet_proc_line - 130 +130 unix_do_one 519 503 -16 do_info 145 97 -48 netstat_main 601 548 -53 tcp_do_one 462 61 -401 raw_do_one 513 107 -406 udp_do_one 533 119 -414 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/6 up/down: 323/-1338) Total: -1015 bytes
Diffstat (limited to 'networking/netstat.c')
-rw-r--r--networking/netstat.c293
1 files changed, 96 insertions, 197 deletions
diff --git a/networking/netstat.c b/networking/netstat.c
index e03ba5fcc..b24628068 100644
--- a/networking/netstat.c
+++ b/networking/netstat.c
@@ -343,11 +343,10 @@ static const char *get_sname(int port, const char *proto, int numeric)
343 343
344static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int numeric) 344static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int numeric)
345{ 345{
346 enum { salen = USE_FEATURE_IPV6(sizeof(struct sockaddr_in6)) SKIP_FEATURE_IPV6(sizeof(struct sockaddr_in)) };
347 char *host, *host_port; 346 char *host, *host_port;
348 347
349 /* Code which used "*" for INADDR_ANY is removed: it's ambiguous in IPv6, 348 /* Code which used "*" for INADDR_ANY is removed: it's ambiguous
350 * while "0.0.0.0" is not. */ 349 * in IPv6, while "0.0.0.0" is not. */
351 350
352 host = numeric ? xmalloc_sockaddr2dotted_noport(addr) 351 host = numeric ? xmalloc_sockaddr2dotted_noport(addr)
353 : xmalloc_sockaddr2host_noport(addr); 352 : xmalloc_sockaddr2host_noport(addr);
@@ -357,112 +356,80 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int
357 return host_port; 356 return host_port;
358} 357}
359 358
360static int tcp_do_one(int lnr, char *line) 359struct inet_params {
361{ 360 int local_port, rem_port, state, uid;
362 char local_addr[64], rem_addr[64];
363 char more[512];
364 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
365#if ENABLE_FEATURE_IPV6 361#if ENABLE_FEATURE_IPV6
366 struct sockaddr_in6 localaddr, remaddr; 362 struct sockaddr_in6 localaddr, remaddr;
367#else 363#else
368 struct sockaddr_in localaddr, remaddr; 364 struct sockaddr_in localaddr, remaddr;
369#endif 365#endif
370 unsigned long rxq, txq, time_len, retr, inode; 366 unsigned long rxq, txq, inode;
367};
371 368
372 if (lnr == 0) 369static int scan_inet_proc_line(struct inet_params *param, char *line)
373 return 0; 370{
371 int num;
372 char local_addr[64], rem_addr[64];
374 373
375 more[0] = '\0';
376 num = sscanf(line, 374 num = sscanf(line,
377 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n", 375 "%*d: %64[0-9A-Fa-f]:%X "
378 &d, local_addr, &local_port, 376 "%64[0-9A-Fa-f]:%X %X "
379 rem_addr, &rem_port, &state, 377 "%lX:%lX %*X:%*X "
380 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more); 378 "%*X %d %*d %ld ",
381 379 local_addr, &param->local_port,
382 if (num < 10) { 380 rem_addr, &param->rem_port, &param->state,
381 &param->txq, &param->rxq,
382 &param->uid, &param->inode);
383 if (num < 9) {
383 return 1; /* error */ 384 return 1; /* error */
384 } 385 }
385 386
386 if (strlen(local_addr) > 8) { 387 if (strlen(local_addr) > 8) {
387#if ENABLE_FEATURE_IPV6 388#if ENABLE_FEATURE_IPV6
388 build_ipv6_addr(local_addr, &localaddr); 389 build_ipv6_addr(local_addr, &param->localaddr);
389 build_ipv6_addr(rem_addr, &remaddr); 390 build_ipv6_addr(rem_addr, &param->remaddr);
390#endif 391#endif
391 } else { 392 } else {
392 build_ipv4_addr(local_addr, &localaddr); 393 build_ipv4_addr(local_addr, &param->localaddr);
393 build_ipv4_addr(rem_addr, &remaddr); 394 build_ipv4_addr(rem_addr, &param->remaddr);
394 } 395 }
396 return 0;
397}
395 398
396 if ((rem_port && (flags & NETSTAT_CONNECTED)) 399static void print_inet_line(struct inet_params *param,
397 || (!rem_port && (flags & NETSTAT_LISTENING)) 400 const char *state_str, const char *proto, int is_connected)
401{
402 if ((is_connected && (flags & NETSTAT_CONNECTED))
403 || (!is_connected && (flags & NETSTAT_LISTENING))
398 ) { 404 ) {
399 char *l = ip_port_str( 405 char *l = ip_port_str(
400 (struct sockaddr *) &localaddr, local_port, 406 (struct sockaddr *) &param->localaddr, param->local_port,
401 "tcp", flags & NETSTAT_NUMERIC); 407 proto, flags & NETSTAT_NUMERIC);
402 char *r = ip_port_str( 408 char *r = ip_port_str(
403 (struct sockaddr *) &remaddr, rem_port, 409 (struct sockaddr *) &param->remaddr, param->rem_port,
404 "tcp", flags & NETSTAT_NUMERIC); 410 proto, flags & NETSTAT_NUMERIC);
405 printf(net_conn_line, 411 printf(net_conn_line,
406 "tcp", rxq, txq, l, r, tcp_state[state]); 412 proto, param->rxq, param->txq, l, r, state_str);
407#if ENABLE_FEATURE_NETSTAT_PRG 413#if ENABLE_FEATURE_NETSTAT_PRG
408 if (option_mask32 & OPT_prg) 414 if (option_mask32 & OPT_prg)
409 printf("%."PROGNAME_WIDTH_STR"s", prg_cache_get(inode)); 415 printf("%."PROGNAME_WIDTH_STR"s", prg_cache_get(param->inode));
410#endif 416#endif
411 bb_putchar('\n'); 417 bb_putchar('\n');
412 free(l); 418 free(l);
413 free(r); 419 free(r);
414 } 420 }
415 return 0;
416} 421}
417 422
418static int udp_do_one(int lnr, char *line) 423static int FAST_FUNC tcp_do_one(char *line)
419{ 424{
420 char local_addr[64], rem_addr[64]; 425 struct inet_params param;
421 const char *state_str;
422 char more[512];
423 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
424#if ENABLE_FEATURE_IPV6
425 struct sockaddr_in6 localaddr, remaddr;
426#else
427 struct sockaddr_in localaddr, remaddr;
428#endif
429 unsigned long rxq, txq, time_len, retr, inode;
430
431 if (lnr == 0)
432 return 0;
433
434 more[0] = '\0';
435 num = sscanf(line,
436 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
437 &d, local_addr, &local_port,
438 rem_addr, &rem_port, &state,
439 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
440 426
441 if (strlen(local_addr) > 8) { 427 if (scan_inet_proc_line(&param, line))
442#if ENABLE_FEATURE_IPV6 428 return 1;
443 /* Demangle what the kernel gives us */
444 build_ipv6_addr(local_addr, &localaddr);
445 build_ipv6_addr(rem_addr, &remaddr);
446#endif
447 } else {
448 build_ipv4_addr(local_addr, &localaddr);
449 build_ipv4_addr(rem_addr, &remaddr);
450 }
451 429
452 if (num < 10) { 430 print_inet_line(&param, tcp_state[param.state], "tcp", param.rem_port);
453 return 1; /* error */ 431 return 0;
454 } 432}
455 switch (state) {
456 case TCP_ESTABLISHED:
457 state_str = "ESTABLISHED";
458 break;
459 case TCP_CLOSE:
460 state_str = "";
461 break;
462 default:
463 state_str = "UNKNOWN";
464 break;
465 }
466 433
467#if ENABLE_FEATURE_IPV6 434#if ENABLE_FEATURE_IPV6
468# define notnull(A) ( \ 435# define notnull(A) ( \
@@ -477,105 +444,53 @@ static int udp_do_one(int lnr, char *line)
477#else 444#else
478# define notnull(A) (A.sin_addr.s_addr) 445# define notnull(A) (A.sin_addr.s_addr)
479#endif 446#endif
480 { 447
481 int have_remaddr = notnull(remaddr); 448static int FAST_FUNC udp_do_one(char *line)
482 if ((have_remaddr && (flags & NETSTAT_CONNECTED)) 449{
483 || (!have_remaddr && (flags & NETSTAT_LISTENING)) 450 int have_remaddr;
484 ) { 451 const char *state_str;
485 char *l = ip_port_str( 452 struct inet_params param;
486 (struct sockaddr *) &localaddr, local_port, 453
487 "udp", flags & NETSTAT_NUMERIC); 454 if (scan_inet_proc_line(&param, line))
488 char *r = ip_port_str( 455 return 1;
489 (struct sockaddr *) &remaddr, rem_port, 456
490 "udp", flags & NETSTAT_NUMERIC); 457 state_str = "UNKNOWN";
491 printf(net_conn_line, 458 switch (param.state) {
492 "udp", rxq, txq, l, r, state_str); 459 case TCP_ESTABLISHED:
493#if ENABLE_FEATURE_NETSTAT_PRG 460 state_str = "ESTABLISHED";
494 if (option_mask32 & OPT_prg) 461 break;
495 printf("%."PROGNAME_WIDTH_STR"s", prg_cache_get(inode)); 462 case TCP_CLOSE:
496#endif 463 state_str = "";
497 bb_putchar('\n'); 464 break;
498 free(l);
499 free(r);
500 }
501 } 465 }
466
467 have_remaddr = notnull(param.remaddr);
468 print_inet_line(&param, state_str, "udp", have_remaddr);
502 return 0; 469 return 0;
503} 470}
504 471
505static int raw_do_one(int lnr, char *line) 472static int FAST_FUNC raw_do_one(char *line)
506{ 473{
507 char local_addr[64], rem_addr[64]; 474 int have_remaddr;
508 char more[512]; 475 struct inet_params param;
509 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
510#if ENABLE_FEATURE_IPV6
511 struct sockaddr_in6 localaddr, remaddr;
512#else
513 struct sockaddr_in localaddr, remaddr;
514#endif
515 unsigned long rxq, txq, time_len, retr, inode;
516
517 if (lnr == 0)
518 return 0;
519
520 more[0] = '\0';
521 num = sscanf(line,
522 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
523 &d, local_addr, &local_port,
524 rem_addr, &rem_port, &state,
525 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
526
527 if (strlen(local_addr) > 8) {
528#if ENABLE_FEATURE_IPV6
529 build_ipv6_addr(local_addr, &localaddr);
530 build_ipv6_addr(rem_addr, &remaddr);
531#endif
532 } else {
533 build_ipv4_addr(local_addr, &localaddr);
534 build_ipv4_addr(rem_addr, &remaddr);
535 }
536 476
537 if (num < 10) { 477 if (scan_inet_proc_line(&param, line))
538 return 1; /* error */ 478 return 1;
539 }
540 479
541 { 480 have_remaddr = notnull(param.remaddr);
542 int have_remaddr = notnull(remaddr); 481 print_inet_line(&param, itoa(param.state), "raw", have_remaddr);
543 if ((have_remaddr && (flags & NETSTAT_CONNECTED))
544 || (!have_remaddr && (flags & NETSTAT_LISTENING))
545 ) {
546 char *l = ip_port_str(
547 (struct sockaddr *) &localaddr, local_port,
548 "raw", flags & NETSTAT_NUMERIC);
549 char *r = ip_port_str(
550 (struct sockaddr *) &remaddr, rem_port,
551 "raw", flags & NETSTAT_NUMERIC);
552 printf(net_conn_line,
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');
559 free(l);
560 free(r);
561 }
562 }
563 return 0; 482 return 0;
564} 483}
565 484
566static int unix_do_one(int nr, char *line) 485static int FAST_FUNC unix_do_one(char *line)
567{ 486{
568 unsigned long refcnt, proto, unix_flags; 487 unsigned long refcnt, proto, unix_flags;
569 unsigned long inode; 488 unsigned long inode;
570 int type, state; 489 int type, state;
571 int num, path_ofs; 490 int num, path_ofs;
572 void *d;
573 const char *ss_proto, *ss_state, *ss_type; 491 const char *ss_proto, *ss_state, *ss_type;
574 char ss_flags[32]; 492 char ss_flags[32];
575 493
576 if (nr == 0)
577 return 0; /* skip header */
578
579 /* 2.6.15 may report lines like "... @/tmp/fam-user-^@^@^@^@^@^@^@..." 494 /* 2.6.15 may report lines like "... @/tmp/fam-user-^@^@^@^@^@^@^@..."
580 * Other users report long lines filled by NUL bytes. 495 * Other users report long lines filled by NUL bytes.
581 * (those ^@ are NUL bytes too). We see them as empty lines. */ 496 * (those ^@ are NUL bytes too). We see them as empty lines. */
@@ -583,9 +498,9 @@ static int unix_do_one(int nr, char *line)
583 return 0; 498 return 0;
584 499
585 path_ofs = 0; /* paranoia */ 500 path_ofs = 0; /* paranoia */
586 num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %n", 501 num = sscanf(line, "%*p: %lX %lX %lX %X %X %lu %n",
587 &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, &path_ofs); 502 &refcnt, &proto, &unix_flags, &type, &state, &inode, &path_ofs);
588 if (num < 7) { 503 if (num < 6) {
589 return 1; /* error */ 504 return 1; /* error */
590 } 505 }
591 if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) { 506 if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) {
@@ -681,34 +596,24 @@ static int unix_do_one(int nr, char *line)
681 return 0; 596 return 0;
682} 597}
683 598
684#define _PATH_PROCNET_UDP "/proc/net/udp" 599static void do_info(const char *file, int FAST_FUNC (*proc)(char *))
685#define _PATH_PROCNET_UDP6 "/proc/net/udp6"
686#define _PATH_PROCNET_TCP "/proc/net/tcp"
687#define _PATH_PROCNET_TCP6 "/proc/net/tcp6"
688#define _PATH_PROCNET_RAW "/proc/net/raw"
689#define _PATH_PROCNET_RAW6 "/proc/net/raw6"
690#define _PATH_PROCNET_UNIX "/proc/net/unix"
691
692static void do_info(const char *file, const char *name, int (*proc)(int, char *))
693{ 600{
694 int lnr; 601 int lnr;
695 FILE *procinfo; 602 FILE *procinfo;
696 char *buffer; 603 char *buffer;
697 604
698 procinfo = fopen_for_read(file); 605 /* _stdin is just to save "r" param */
606 procinfo = fopen_or_warn_stdin(file);
699 if (procinfo == NULL) { 607 if (procinfo == NULL) {
700 if (errno != ENOENT) {
701 bb_simple_perror_msg(file);
702 } else {
703 bb_error_msg("no kernel support for %s", name);
704 }
705 return; 608 return;
706 } 609 }
707 lnr = 0; 610 lnr = 0;
708 /* Why? because xmalloc_fgets_str doesn't stop on NULs */ 611 /* Why xmalloc_fgets_str? because it doesn't stop on NULs */
709 while ((buffer = xmalloc_fgets_str(procinfo, "\n")) != NULL) { 612 while ((buffer = xmalloc_fgets_str(procinfo, "\n")) != NULL) {
710 if (proc(lnr++, buffer)) 613 /* line 0 is skipped */
711 bb_error_msg("%s: bogus data on line %d", file, lnr); 614 if (lnr && proc(buffer))
615 bb_error_msg("%s: bogus data on line %d", file, lnr + 1);
616 lnr++;
712 free(buffer); 617 free(buffer);
713 } 618 }
714 fclose(procinfo); 619 fclose(procinfo);
@@ -719,12 +624,6 @@ int netstat_main(int argc UNUSED_PARAM, char **argv)
719{ 624{
720 const char *net_conn_line_header = PRINT_NET_CONN_HEADER; 625 const char *net_conn_line_header = PRINT_NET_CONN_HEADER;
721 unsigned opt; 626 unsigned opt;
722#if ENABLE_FEATURE_IPV6
723 smallint inet = 1;
724 smallint inet6 = 1;
725#else
726 enum { inet = 1, inet6 = 0 };
727#endif
728 627
729 INIT_G(); 628 INIT_G();
730 629
@@ -777,24 +676,24 @@ int netstat_main(int argc UNUSED_PARAM, char **argv)
777 print_progname_banner(); 676 print_progname_banner();
778 bb_putchar('\n'); 677 bb_putchar('\n');
779 } 678 }
780 if (inet && (flags & NETSTAT_TCP)) 679 if (flags & NETSTAT_TCP) {
781 do_info(_PATH_PROCNET_TCP, "AF INET (tcp)", tcp_do_one); 680 do_info("/proc/net/tcp", tcp_do_one);
782#if ENABLE_FEATURE_IPV6 681#if ENABLE_FEATURE_IPV6
783 if (inet6 && (flags & NETSTAT_TCP)) 682 do_info("/proc/net/tcp6", tcp_do_one);
784 do_info(_PATH_PROCNET_TCP6, "AF INET6 (tcp)", tcp_do_one);
785#endif 683#endif
786 if (inet && (flags & NETSTAT_UDP)) 684 }
787 do_info(_PATH_PROCNET_UDP, "AF INET (udp)", udp_do_one); 685 if (flags & NETSTAT_UDP) {
686 do_info("/proc/net/udp", udp_do_one);
788#if ENABLE_FEATURE_IPV6 687#if ENABLE_FEATURE_IPV6
789 if (inet6 && (flags & NETSTAT_UDP)) 688 do_info("/proc/net/udp6", udp_do_one);
790 do_info(_PATH_PROCNET_UDP6, "AF INET6 (udp)", udp_do_one);
791#endif 689#endif
792 if (inet && (flags & NETSTAT_RAW)) 690 }
793 do_info(_PATH_PROCNET_RAW, "AF INET (raw)", raw_do_one); 691 if (flags & NETSTAT_RAW) {
692 do_info("/proc/net/raw", raw_do_one);
794#if ENABLE_FEATURE_IPV6 693#if ENABLE_FEATURE_IPV6
795 if (inet6 && (flags & NETSTAT_RAW)) 694 do_info("/proc/net/raw6", raw_do_one);
796 do_info(_PATH_PROCNET_RAW6, "AF INET6 (raw)", raw_do_one);
797#endif 695#endif
696 }
798 if (flags & NETSTAT_UNIX) { 697 if (flags & NETSTAT_UNIX) {
799 printf("Active UNIX domain sockets "); 698 printf("Active UNIX domain sockets ");
800 if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) == (NETSTAT_LISTENING|NETSTAT_CONNECTED)) 699 if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) == (NETSTAT_LISTENING|NETSTAT_CONNECTED))
@@ -806,7 +705,7 @@ int netstat_main(int argc UNUSED_PARAM, char **argv)
806 printf("\nProto RefCnt Flags Type State I-Node "); 705 printf("\nProto RefCnt Flags Type State I-Node ");
807 print_progname_banner(); 706 print_progname_banner();
808 printf("Path\n"); 707 printf("Path\n");
809 do_info(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one); 708 do_info("/proc/net/unix", unix_do_one);
810 } 709 }
811 prg_cache_clear(); 710 prg_cache_clear();
812 return 0; 711 return 0;