aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2003-08-02 00:04:18 +0000
committerManuel Novoa III <mjn3@codepoet.org>2003-08-02 00:04:18 +0000
commitb1d5b741ac310cda14c6b9c49a9853e82fe6654f (patch)
tree14a34439f49785e8e769fcdd4f5d263458b9a288
parent546f21aa2decef2382690deea8b8e901146b1557 (diff)
downloadbusybox-w32-b1d5b741ac310cda14c6b9c49a9853e82fe6654f.tar.gz
busybox-w32-b1d5b741ac310cda14c6b9c49a9853e82fe6654f.tar.bz2
busybox-w32-b1d5b741ac310cda14c6b9c49a9853e82fe6654f.zip
Save 0.5K.
-rw-r--r--libbb/interface.c283
1 files changed, 154 insertions, 129 deletions
diff --git a/libbb/interface.c b/libbb/interface.c
index 47358fe0d..394ba5f4c 100644
--- a/libbb/interface.c
+++ b/libbb/interface.c
@@ -15,7 +15,7 @@
15 * that either displays or sets the characteristics of 15 * that either displays or sets the characteristics of
16 * one or more of the system's networking interfaces. 16 * one or more of the system's networking interfaces.
17 * 17 *
18 * Version: $Id: interface.c,v 1.18 2003/07/28 06:35:32 andersen Exp $ 18 * Version: $Id: interface.c,v 1.19 2003/08/02 00:04:18 mjn3 Exp $
19 * 19 *
20 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> 20 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
21 * and others. Copyright 1993 MicroWalt Corporation 21 * and others. Copyright 1993 MicroWalt Corporation
@@ -87,8 +87,6 @@
87#define new(p) ((p) = xcalloc(1,sizeof(*(p)))) 87#define new(p) ((p) = xcalloc(1,sizeof(*(p))))
88#define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (patch)) 88#define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (patch))
89 89
90static int procnetdev_vsn = 1;
91
92#ifdef HAVE_HWSLIP 90#ifdef HAVE_HWSLIP
93#include <net/if_slip.h> 91#include <net/if_slip.h>
94#endif 92#endif
@@ -1021,71 +1019,76 @@ static char *get_name(char *name, char *p)
1021 return p; 1019 return p;
1022} 1020}
1023 1021
1024static int get_dev_fields(char *bp, struct interface *ife) 1022/* If scanf supports size qualifiers for %n conversions, then we can
1023 * use a modified fmt that simply stores the position in the fields
1024 * having no associated fields in the proc string. Of course, we need
1025 * to zero them again when we're done. But that is smaller than the
1026 * old approach of multiple scanf occurrences with large numbers of
1027 * args. */
1028
1029/* static const char *ss_fmt[] = { */
1030/* "%Ln%Lu%lu%lu%lu%lu%ln%ln%Ln%Lu%lu%lu%lu%lu%lu", */
1031/* "%Lu%Lu%lu%lu%lu%lu%ln%ln%Lu%Lu%lu%lu%lu%lu%lu", */
1032/* "%Lu%Lu%lu%lu%lu%lu%lu%lu%Lu%Lu%lu%lu%lu%lu%lu%lu" */
1033/* }; */
1034
1035 /* Lie about the size of the int pointed to for %n. */
1036#if INT_MAX == LONG_MAX
1037static const char *ss_fmt[] = {
1038 "%n%Lu%u%u%u%u%n%n%n%Lu%u%u%u%u%u",
1039 "%Lu%Lu%u%u%u%u%n%n%Lu%Lu%u%u%u%u%u",
1040 "%Lu%Lu%u%u%u%u%u%u%Lu%Lu%u%u%u%u%u%u"
1041};
1042#else
1043static const char *ss_fmt[] = {
1044 "%n%Lu%lu%lu%lu%lu%n%n%n%Lu%lu%lu%lu%lu%lu",
1045 "%Lu%Lu%lu%lu%lu%lu%n%n%Lu%Lu%lu%lu%lu%lu%lu",
1046 "%Lu%Lu%lu%lu%lu%lu%lu%lu%Lu%Lu%lu%lu%lu%lu%lu%lu"
1047};
1048
1049#endif
1050
1051static void get_dev_fields(char *bp, struct interface *ife, int procnetdev_vsn)
1025{ 1052{
1026 switch (procnetdev_vsn) { 1053 memset(&ife->stats, 0, sizeof(struct user_net_device_stats));
1027 case 3: 1054
1028 sscanf(bp, 1055 sscanf(bp, ss_fmt[procnetdev_vsn],
1029 "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu %lu", 1056 &ife->stats.rx_bytes, /* missing for 0 */
1030 &ife->stats.rx_bytes, 1057 &ife->stats.rx_packets,
1031 &ife->stats.rx_packets, 1058 &ife->stats.rx_errors,
1032 &ife->stats.rx_errors, 1059 &ife->stats.rx_dropped,
1033 &ife->stats.rx_dropped, 1060 &ife->stats.rx_fifo_errors,
1034 &ife->stats.rx_fifo_errors, 1061 &ife->stats.rx_frame_errors,
1035 &ife->stats.rx_frame_errors, 1062 &ife->stats.rx_compressed, /* missing for <= 1 */
1036 &ife->stats.rx_compressed, 1063 &ife->stats.rx_multicast, /* missing for <= 1 */
1037 &ife->stats.rx_multicast, 1064 &ife->stats.tx_bytes, /* missing for 0 */
1038 &ife->stats.tx_bytes, 1065 &ife->stats.tx_packets,
1039 &ife->stats.tx_packets, 1066 &ife->stats.tx_errors,
1040 &ife->stats.tx_errors, 1067 &ife->stats.tx_dropped,
1041 &ife->stats.tx_dropped, 1068 &ife->stats.tx_fifo_errors,
1042 &ife->stats.tx_fifo_errors, 1069 &ife->stats.collisions,
1043 &ife->stats.collisions, 1070 &ife->stats.tx_carrier_errors,
1044 &ife->stats.tx_carrier_errors, &ife->stats.tx_compressed); 1071 &ife->stats.tx_compressed /* missing for <= 1 */
1045 break; 1072 );
1046 case 2: 1073
1047 sscanf(bp, "%Lu %Lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu", 1074 if (procnetdev_vsn <= 1) {
1048 &ife->stats.rx_bytes, 1075 if (procnetdev_vsn == 0) {
1049 &ife->stats.rx_packets, 1076 ife->stats.rx_bytes = 0;
1050 &ife->stats.rx_errors, 1077 ife->stats.tx_bytes = 0;
1051 &ife->stats.rx_dropped, 1078 }
1052 &ife->stats.rx_fifo_errors,
1053 &ife->stats.rx_frame_errors,
1054 &ife->stats.tx_bytes,
1055 &ife->stats.tx_packets,
1056 &ife->stats.tx_errors,
1057 &ife->stats.tx_dropped,
1058 &ife->stats.tx_fifo_errors,
1059 &ife->stats.collisions, &ife->stats.tx_carrier_errors);
1060 ife->stats.rx_multicast = 0;
1061 break;
1062 case 1:
1063 sscanf(bp, "%Lu %lu %lu %lu %lu %Lu %lu %lu %lu %lu %lu",
1064 &ife->stats.rx_packets,
1065 &ife->stats.rx_errors,
1066 &ife->stats.rx_dropped,
1067 &ife->stats.rx_fifo_errors,
1068 &ife->stats.rx_frame_errors,
1069 &ife->stats.tx_packets,
1070 &ife->stats.tx_errors,
1071 &ife->stats.tx_dropped,
1072 &ife->stats.tx_fifo_errors,
1073 &ife->stats.collisions, &ife->stats.tx_carrier_errors);
1074 ife->stats.rx_bytes = 0;
1075 ife->stats.tx_bytes = 0;
1076 ife->stats.rx_multicast = 0; 1079 ife->stats.rx_multicast = 0;
1077 break; 1080 ife->stats.rx_compressed = 0;
1081 ife->stats.tx_compressed = 0;
1078 } 1082 }
1079 return 0;
1080} 1083}
1081 1084
1082static inline int procnetdev_version(char *buf) 1085static inline int procnetdev_version(char *buf)
1083{ 1086{
1084 if (strstr(buf, "compressed")) 1087 if (strstr(buf, "compressed"))
1085 return 3;
1086 if (strstr(buf, "bytes"))
1087 return 2; 1088 return 2;
1088 return 1; 1089 if (strstr(buf, "bytes"))
1090 return 1;
1091 return 0;
1089} 1092}
1090 1093
1091static int if_readlist_proc(char *target) 1094static int if_readlist_proc(char *target)
@@ -1094,7 +1097,7 @@ static int if_readlist_proc(char *target)
1094 FILE *fh; 1097 FILE *fh;
1095 char buf[512]; 1098 char buf[512];
1096 struct interface *ife; 1099 struct interface *ife;
1097 int err; 1100 int err, procnetdev_vsn;
1098 1101
1099 if (proc_read) 1102 if (proc_read)
1100 return 0; 1103 return 0;
@@ -1109,28 +1112,7 @@ static int if_readlist_proc(char *target)
1109 fgets(buf, sizeof buf, fh); /* eat line */ 1112 fgets(buf, sizeof buf, fh); /* eat line */
1110 fgets(buf, sizeof buf, fh); 1113 fgets(buf, sizeof buf, fh);
1111 1114
1112#if 0 /* pretty, but can't cope with missing fields */
1113 fmt = proc_gen_fmt(_PATH_PROCNET_DEV, 1, fh, "face", "", /* parsed separately */
1114 "bytes", "%lu",
1115 "packets", "%lu",
1116 "errs", "%lu",
1117 "drop", "%lu",
1118 "fifo", "%lu",
1119 "frame", "%lu",
1120 "compressed", "%lu",
1121 "multicast", "%lu",
1122 "bytes", "%lu",
1123 "packets", "%lu",
1124 "errs", "%lu",
1125 "drop", "%lu",
1126 "fifo", "%lu",
1127 "colls", "%lu",
1128 "carrier", "%lu", "compressed", "%lu", NULL);
1129 if (!fmt)
1130 return -1;
1131#else
1132 procnetdev_vsn = procnetdev_version(buf); 1115 procnetdev_vsn = procnetdev_version(buf);
1133#endif
1134 1116
1135 err = 0; 1117 err = 0;
1136 while (fgets(buf, sizeof buf, fh)) { 1118 while (fgets(buf, sizeof buf, fh)) {
@@ -1138,7 +1120,7 @@ static int if_readlist_proc(char *target)
1138 1120
1139 s = get_name(name, buf); 1121 s = get_name(name, buf);
1140 ife = add_interface(name); 1122 ife = add_interface(name);
1141 get_dev_fields(s, ife); 1123 get_dev_fields(s, ife, procnetdev_vsn);
1142 ife->statistics_valid = 1; 1124 ife->statistics_valid = 1;
1143 if (target && !strcmp(target, name)) 1125 if (target && !strcmp(target, name))
1144 break; 1126 break;
@@ -1148,9 +1130,6 @@ static int if_readlist_proc(char *target)
1148 err = -1; 1130 err = -1;
1149 proc_read = 0; 1131 proc_read = 0;
1150 } 1132 }
1151#if 0
1152 free(fmt);
1153#endif
1154 fclose(fh); 1133 fclose(fh);
1155 return err; 1134 return err;
1156} 1135}
@@ -1670,7 +1649,8 @@ static void hwinit()
1670#endif /* KEEP_UNUSED */ 1649#endif /* KEEP_UNUSED */
1671 1650
1672#ifdef IFF_PORTSEL 1651#ifdef IFF_PORTSEL
1673static const char *if_port_text[][4] = { 1652#if 0
1653static const char * const if_port_text[][4] = {
1674 /* Keep in step with <linux/netdevice.h> */ 1654 /* Keep in step with <linux/netdevice.h> */
1675 {"unknown", NULL, NULL, NULL}, 1655 {"unknown", NULL, NULL, NULL},
1676 {"10base2", "bnc", "coax", NULL}, 1656 {"10base2", "bnc", "coax", NULL},
@@ -1681,6 +1661,19 @@ static const char *if_port_text[][4] = {
1681 {"100baseFX", NULL, NULL, NULL}, 1661 {"100baseFX", NULL, NULL, NULL},
1682 {NULL, NULL, NULL, NULL}, 1662 {NULL, NULL, NULL, NULL},
1683}; 1663};
1664#else
1665static const char * const if_port_text[] = {
1666 /* Keep in step with <linux/netdevice.h> */
1667 "unknown",
1668 "10base2",
1669 "10baseT",
1670 "AUI",
1671 "100baseT",
1672 "100baseTX",
1673 "100baseFX",
1674 NULL
1675};
1676#endif
1684#endif 1677#endif
1685 1678
1686/* Check our hardware type table for this type. */ 1679/* Check our hardware type table for this type. */
@@ -1714,29 +1707,83 @@ static int hw_null_address(struct hwtype *hw, void *ap)
1714 return 1; 1707 return 1;
1715} 1708}
1716 1709
1717static const char TRext[] = "\0\0k\0M"; 1710#warning devel code
1711static const char TRext[] = "\0\0\0Ki\0Mi\0Gi\0Ti";
1718 1712
1719static void print_bytes_scaled(unsigned long long ull, const char *end) 1713static void print_bytes_scaled(unsigned long long ull, const char *end)
1720{ 1714{
1721 unsigned long long int_part; 1715 unsigned long long int_part;
1722 unsigned long frac_part;
1723 const char *ext; 1716 const char *ext;
1717 unsigned int frac_part;
1724 int i; 1718 int i;
1725 1719
1726 frac_part = 0; 1720 frac_part = 0;
1727 ext = TRext; 1721 ext = TRext;
1728 int_part = ull; 1722 int_part = ull;
1729 for (i = 0; i < 2; i++) { 1723 i = 4;
1724 do {
1725#if 0
1726 /* This does correct rounding and is a little larger. But it
1727 * uses KiB as the smallest displayed unit. */
1728 if ((int_part < (1024*1024 - 51)) || !--i) {
1729 i = 0;
1730 int_part += 51; /* 1024*.05 = 51.2 */
1731 frac_part = ((((unsigned int) int_part) & (1024-1)) * 10) / 1024;
1732 }
1733 int_part /= 1024;
1734 ext += 3; /* KiB, MiB, GiB, TiB */
1735#else
1730 if (int_part >= 1024) { 1736 if (int_part >= 1024) {
1731 frac_part = ((int_part % 1024) * 10) / 1024; 1737 frac_part = ((((unsigned int) int_part) & (1024-1)) * 10) / 1024;
1732 int_part /= 1024; 1738 int_part /= 1024;
1733 ext += 2; /* Kb, Mb */ 1739 ext += 3; /* KiB, MiB, GiB, TiB */
1734 } 1740 }
1735 } 1741 --i;
1742#endif
1743 } while (i);
1736 1744
1737 printf("X bytes:%Lu (%Lu.%lu %siB)%s", ull, int_part, frac_part, ext, end); 1745 printf("X bytes:%Lu (%Lu.%u %sB)%s", ull, int_part, frac_part, ext, end);
1738} 1746}
1739 1747
1748static const char * const ife_print_flags_strs[] = {
1749 "UP ",
1750 "BROADCAST ",
1751 "DEBUG ",
1752 "LOOPBACK ",
1753 "POINTOPOINT ",
1754 "NOTRAILERS ",
1755 "RUNNING ",
1756 "NOARP ",
1757 "PROMISC ",
1758 "ALLMULTI ",
1759 "SLAVE ",
1760 "MASTER ",
1761 "MULTICAST ",
1762#ifdef HAVE_DYNAMIC
1763 "DYNAMIC "
1764#endif
1765};
1766
1767static const unsigned short ife_print_flags_mask[] = {
1768 IFF_UP,
1769 IFF_BROADCAST,
1770 IFF_DEBUG,
1771 IFF_LOOPBACK,
1772 IFF_POINTOPOINT,
1773 IFF_NOTRAILERS,
1774 IFF_RUNNING,
1775 IFF_NOARP,
1776 IFF_PROMISC,
1777 IFF_ALLMULTI,
1778 IFF_SLAVE,
1779 IFF_MASTER,
1780 IFF_MULTICAST,
1781#ifdef HAVE_DYNAMIC
1782 IFF_DYNAMIC
1783#endif
1784 0
1785};
1786
1740static void ife_print(struct interface *ptr) 1787static void ife_print(struct interface *ptr)
1741{ 1788{
1742 struct aftype *ap; 1789 struct aftype *ap;
@@ -1782,7 +1829,7 @@ static void ife_print(struct interface *ptr)
1782 printf(_("HWaddr %s "), hw->print(ptr->hwaddr)); 1829 printf(_("HWaddr %s "), hw->print(ptr->hwaddr));
1783#ifdef IFF_PORTSEL 1830#ifdef IFF_PORTSEL
1784 if (ptr->flags & IFF_PORTSEL) { 1831 if (ptr->flags & IFF_PORTSEL) {
1785 printf(_("Media:%s"), if_port_text[ptr->map.port][0]); 1832 printf(_("Media:%s"), if_port_text[ptr->map.port] /* [0] */);
1786 if (ptr->flags & IFF_AUTOMEDIA) 1833 if (ptr->flags & IFF_AUTOMEDIA)
1787 printf(_("(auto)")); 1834 printf(_("(auto)"));
1788 } 1835 }
@@ -1907,38 +1954,18 @@ static void ife_print(struct interface *ptr)
1907 1954
1908 printf(" "); 1955 printf(" ");
1909 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */ 1956 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */
1910 if (ptr->flags == 0) 1957
1958 if (ptr->flags == 0) {
1911 printf(_("[NO FLAGS] ")); 1959 printf(_("[NO FLAGS] "));
1912 if (ptr->flags & IFF_UP) 1960 } else {
1913 printf(_("UP ")); 1961 int i = 0;
1914 if (ptr->flags & IFF_BROADCAST) 1962 do {
1915 printf(_("BROADCAST ")); 1963 if (ptr->flags & ife_print_flags_mask[i]) {
1916 if (ptr->flags & IFF_DEBUG) 1964 printf(_(ife_print_flags_strs[i]));
1917 printf(_("DEBUG ")); 1965 }
1918 if (ptr->flags & IFF_LOOPBACK) 1966 } while (ife_print_flags_mask[++i]);
1919 printf(_("LOOPBACK ")); 1967 }
1920 if (ptr->flags & IFF_POINTOPOINT) 1968
1921 printf(_("POINTOPOINT "));
1922 if (ptr->flags & IFF_NOTRAILERS)
1923 printf(_("NOTRAILERS "));
1924 if (ptr->flags & IFF_RUNNING)
1925 printf(_("RUNNING "));
1926 if (ptr->flags & IFF_NOARP)
1927 printf(_("NOARP "));
1928 if (ptr->flags & IFF_PROMISC)
1929 printf(_("PROMISC "));
1930 if (ptr->flags & IFF_ALLMULTI)
1931 printf(_("ALLMULTI "));
1932 if (ptr->flags & IFF_SLAVE)
1933 printf(_("SLAVE "));
1934 if (ptr->flags & IFF_MASTER)
1935 printf(_("MASTER "));
1936 if (ptr->flags & IFF_MULTICAST)
1937 printf(_("MULTICAST "));
1938#ifdef HAVE_DYNAMIC
1939 if (ptr->flags & IFF_DYNAMIC)
1940 printf(_("DYNAMIC "));
1941#endif
1942 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */ 1969 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */
1943 printf(_(" MTU:%d Metric:%d"), ptr->mtu, ptr->metric ? ptr->metric : 1); 1970 printf(_(" MTU:%d Metric:%d"), ptr->mtu, ptr->metric ? ptr->metric : 1);
1944#ifdef SIOCSKEEPALIVE 1971#ifdef SIOCSKEEPALIVE
@@ -1956,8 +1983,7 @@ static void ife_print(struct interface *ptr)
1956 */ 1983 */
1957 printf(" "); 1984 printf(" ");
1958 1985
1959 printf(_ 1986 printf(_("RX packets:%Lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
1960 ("RX packets:%Lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
1961 ptr->stats.rx_packets, ptr->stats.rx_errors, 1987 ptr->stats.rx_packets, ptr->stats.rx_errors,
1962 ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, 1988 ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors,
1963 ptr->stats.rx_frame_errors); 1989 ptr->stats.rx_frame_errors);
@@ -1965,8 +1991,7 @@ static void ife_print(struct interface *ptr)
1965 printf(_(" compressed:%lu\n"), 1991 printf(_(" compressed:%lu\n"),
1966 ptr->stats.rx_compressed); 1992 ptr->stats.rx_compressed);
1967 printf(" "); 1993 printf(" ");
1968 printf(_ 1994 printf(_("TX packets:%Lu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
1969 ("TX packets:%Lu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
1970 ptr->stats.tx_packets, ptr->stats.tx_errors, 1995 ptr->stats.tx_packets, ptr->stats.tx_errors,
1971 ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, 1996 ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors,
1972 ptr->stats.tx_carrier_errors); 1997 ptr->stats.tx_carrier_errors);