diff --git a/tools/tools/ifinfo/Makefile b/tools/tools/ifinfo/Makefile new file mode 100644 index 000000000000..740a553e275b --- /dev/null +++ b/tools/tools/ifinfo/Makefile @@ -0,0 +1,7 @@ +# $Id$ + +PROG= ifinfo +SRCS= ifinfo.c rfc1650.c +NOMAN= + +.include diff --git a/tools/tools/ifinfo/ifinfo.c b/tools/tools/ifinfo/ifinfo.c new file mode 100644 index 000000000000..14023fa558a4 --- /dev/null +++ b/tools/tools/ifinfo/ifinfo.c @@ -0,0 +1,272 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +#include +#include /* for PF_LINK */ +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ifinfo.h" + +static void printit(const struct ifmibdata *); +static const char *iftype(int); +static const char *ifphys(int, int); +static int isit(int, char **, const char *); +static printfcn findlink(int); + +static void +usage(const char *argv0) +{ + fprintf(stderr, "%s: usage:\n\t%s [-i] [ifnames...]\n", + argv0, argv0); + exit(EX_USAGE); +} + +int +main(int argc, char **argv) +{ + int i, maxifno, retval; + struct ifmibdata ifmd; + int name[6]; + size_t len; + int c; + int dolink = 0; + void *linkmib; + size_t linkmiblen; + printfcn pf; + + while ((c = getopt(argc, argv, "l")) != -1) { + switch(c) { + case 'l': + dolink = 1; + break; + default: + usage(argv[0]); + } + } + + retval = 1; + + name[0] = CTL_NET; + name[1] = PF_LINK; + name[2] = NETLINK_GENERIC; + name[3] = IFMIB_SYSTEM; + name[4] = IFMIB_IFCOUNT; + + len = sizeof maxifno; + if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0) + err(EX_OSERR, "sysctl(net.link.generic.system.ifcount)"); + + for (i = 1; i <= maxifno; i++) { + len = sizeof ifmd; + name[3] = IFMIB_IFDATA; + name[4] = i; + name[5] = IFDATA_GENERAL; + if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) + err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)", + i); + + if (!isit(argc - optind, argv + optind, ifmd.ifmd_name)) + continue; + printit(&ifmd); + if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) { + name[5] = IFDATA_LINKSPECIFIC; + if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0) + err(EX_OSERR, + "sysctl(net.link.ifdata.%d.linkspec) size", + i); + linkmib = malloc(linkmiblen); + if (!linkmib) + err(EX_OSERR, "malloc(%lu)", + (u_long)linkmiblen); + if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0) + err(EX_OSERR, + "sysctl(net.link.ifdata.%d.linkspec)", + i); + pf(linkmib, linkmiblen); + free(linkmib); + } + retval = 0; + } + + return retval; +} + +static void +printit(const struct ifmibdata *ifmd) +{ + printf("Interface %.*s:\n", IFNAMSIZ, ifmd->ifmd_name); + printf("\tflags: %x\n", ifmd->ifmd_flags); + printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount); + printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len); + printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen); + printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops); + printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type)); + printf("\tphysical: %s\n", ifphys(ifmd->ifmd_data.ifi_type, + ifmd->ifmd_data.ifi_physical)); + printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen); + printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen); + printf("\treceive quota: %d\n", ifmd->ifmd_data.ifi_recvquota); + printf("\ttransmit quota: %d\n", ifmd->ifmd_data.ifi_xmitquota); + printf("\tmtu: %lu\n", ifmd->ifmd_data.ifi_mtu); + printf("\tmetric: %lu\n", ifmd->ifmd_data.ifi_metric); + printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate); + printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets); + printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors); + printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets); + printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors); + printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions); + printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes); + printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes); + printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts); + printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts); + printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops); + printf("\tpackets for unknown protocol: %lu\n", + ifmd->ifmd_data.ifi_noproto); + printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming); + printf("\ttransmit timing: %lu usec\n", + ifmd->ifmd_data.ifi_xmittiming); +} + +static const char *const if_types[] = { + "reserved", + "other", + "BBN 1822", + "HDH 1822", + "X.25 DDN", + "X.25", + "Ethernet", + "ISO 8802-3 CSMA/CD", + "ISO 8802-4 Token Bus", + "ISO 8802-5 Token Ring", + "ISO 8802-6 DQDB MAN", + "StarLAN", + "Proteon proNET-10", + "Proteon proNET-80", + "HyperChannel", + "FDDI", + "LAP-B", + "SDLC", + "T-1", + "CEPT", + "Basic rate ISDN", + "Primary rate ISDN", + "Proprietary P2P", + "PPP", + "Loopback", + "ISO CLNP over IP", + "Experimental Ethernet", + "XNS over IP", + "SLIP", + "Ultra Technologies", + "DS-3", + "SMDS", + "Frame Relay", + "RS-232 serial", + "Parallel printer port", + "ARCNET", + "ARCNET+", + "ATM", + "MIOX25", + "SONET/SDH", + "X25PLE", + "ISO 8802-2 LLC", + "LocalTalk", + "SMDSDXI", + "Frame Relay DCE", + "V.35", + "HSSI", + "HIPPI", + "Generic Modem", + "ATM AAL5", + "SONETPATH", + "SONETVT", + "SMDS InterCarrier Interface", + "Proprietary virtual interface", + "Proprietary multiplexing" +}; +#define NIFTYPES ((sizeof if_types)/(sizeof if_types[0])) + +static const char * +iftype(int type) +{ + static char buf[256]; + + if (type <= 0 || type > NIFTYPES) { + sprintf(buf, "unknown type %d", type); + return buf; + } + + return if_types[type]; +} + +static const char * +ifphys(int type, int phys) +{ + static char buf[256]; + + sprintf(buf, "unknown physical %d", phys); + return buf; +} + +static int +isit(int argc, char **argv, const char *name) +{ + if (argc == 0) + return 1; + for (argc = 0; argv[argc]; argc++) { + if (strncmp(argv[argc], name, IFNAMSIZ) == 0) + return 1; + } + return 0; +} + +static printfcn +findlink(int type) +{ + switch(type) { + case IFT_ETHER: + case IFT_ISO88023: + case IFT_STARLAN: + return print_1650; + } + + return 0; +} diff --git a/tools/tools/ifinfo/ifinfo.h b/tools/tools/ifinfo/ifinfo.h new file mode 100644 index 000000000000..24bd4761a2a8 --- /dev/null +++ b/tools/tools/ifinfo/ifinfo.h @@ -0,0 +1,38 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +#ifndef ifinfo_h +#define ifinfo_h 1 + +typedef void (*printfcn)(const void *, size_t); + +extern void print_1650(const void *, size_t); + +#endif /* ifinfo_h */ diff --git a/tools/tools/ifinfo/rfc1650.c b/tools/tools/ifinfo/rfc1650.c new file mode 100644 index 000000000000..534787197c88 --- /dev/null +++ b/tools/tools/ifinfo/rfc1650.c @@ -0,0 +1,124 @@ +#include +#include /* for PF_LINK */ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "ifinfo.h" + +#define print(msg, var) \ + if (var) printf("\t" msg ": %lu\n", (u_long)var) + +static void identify_chipset(u_int32_t chipset); + +void +print_1650(const void *xmd, size_t len) +{ + const struct ifmib_iso_8802_3 *md = xmd; + + if (len != sizeof *md) + warnx("cannot interpret %lu bytes of MIB data", (u_long)len); + + identify_chipset(md->dot3StatsEtherChipSet); + print("Alignment errors", md->dot3StatsAlignmentErrors); + print("FCS errors", md->dot3StatsFCSErrors); + print("Single-collision frames", md->dot3StatsSingleCollisionFrames); + print("Multiple-collision frames", md->dot3StatsMultipleCollisionFrames); + print("SQE (Heartbeat) test errors", md->dot3StatsSQETestErrors); + print("Deferred transmissions", md->dot3StatsDeferredTransmissions); + print("Late collisions", md->dot3StatsLateCollisions); + print("Excessive collisions", md->dot3StatsExcessiveCollisions); + print("Internal transmit errors", md->dot3StatsInternalMacTransmitErrors); + print("Carrier sense errors", md->dot3StatsCarrierSenseErrors); + print("Frame-too-long errors", md->dot3StatsFrameTooLongs); + print("Internal receive errors", md->dot3StatsInternalMacReceiveErrors); + print("Missed frames", md->dot3StatsMissedFrames); +#define cprint(num) print("Packets with " #num " collisions", \ + md->dot3StatsCollFrequencies[num - 1]) + if (md->dot3Compliance >= DOT3COMPLIANCE_COLLS) { + cprint(1); cprint(2); cprint(3); cprint(4); + cprint(5); cprint(6); cprint(7); cprint(8); + cprint(9); cprint(10); cprint(11); cprint(12); + cprint(13); cprint(14); cprint(15); cprint(16); + } + switch(md->dot3Compliance) { + case DOT3COMPLIANCE_STATS: + printf("\tCompliance: statistics only\n"); + break; + case DOT3COMPLIANCE_COLLS: + printf("\tCompliance: statistics and collisions\n"); + break; + } +} + +static const char *const amd[] = { + 0, "Am7990", "Am79900", "Am79C940" +}; + +static const char *const intel[] = { + 0, "82586", "82596", "82557" +}; + +static const char *const national[] = { + 0, "8390", "Sonic" +}; + +static const char *const fujitsu[] = { + 0, "86950" +}; + +static const char *const digital[] = { + 0, "DC21040", "DC21140", "DC21041", "DC21140A", "DC21142" +}; + +static const char *const westerndigital[] = { + 0, "83C690", "83C790" +}; + +#define vendor(name, sets) { name, sets, (sizeof sets)/(sizeof sets[0]) } +static struct { + const char *name; + const char *const *chips; + size_t len; +} chipset_names[] = { + { 0 }, + vendor("AMD", amd), + vendor("Intel", intel), + { 0 }, + vendor("National Semiconductor", national), + vendor("Fujitsu", fujitsu), + vendor("Digital", digital), + vendor("Western Digital", westerndigital) +}; + +static void +identify_chipset(u_int32_t chipset) +{ + enum dot3Vendors vendor = DOT3CHIPSET_VENDOR(chipset); + u_int part = DOT3CHIPSET_PART(chipset); + + printf("\tChipset: "); + if (vendor < 1 + || vendor >= (sizeof chipset_names)/(sizeof chipset_names[0]) + || !chipset_names[vendor].name) { + printf("unknown\n"); + return; + } + + printf("%s ", chipset_names[vendor].name); + if (part < 1 || part >= chipset_names[vendor].len) { + printf("unknown\n"); + return; + } + + printf("%s\n", chipset_names[vendor].chips[part]); +} +