summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1996-10-11 15:56:41 +0000
committerwollman <wollman@FreeBSD.org>1996-10-11 15:56:41 +0000
commit8c20987747a9efa25cdc08a0f1d0acce275529bb (patch)
tree0e9f3cf45073ef67a2243c75f1c806b290cbf9e5 /tools
parent317c834418c2c9756a486ef65299298c1ccff6f7 (diff)
downloadFreeBSD-src-8c20987747a9efa25cdc08a0f1d0acce275529bb.zip
FreeBSD-src-8c20987747a9efa25cdc08a0f1d0acce275529bb.tar.gz
Add my little `ifinfo' program. This is sort of a cross between a
diagnostic program for debugging the interface MIB and an example of how to use same. Someday, netstat should be updated to print this information in a prettier form.
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/ifinfo/Makefile7
-rw-r--r--tools/tools/ifinfo/ifinfo.c272
-rw-r--r--tools/tools/ifinfo/ifinfo.h38
-rw-r--r--tools/tools/ifinfo/rfc1650.c124
4 files changed, 441 insertions, 0 deletions
diff --git a/tools/tools/ifinfo/Makefile b/tools/tools/ifinfo/Makefile
new file mode 100644
index 0000000..740a553
--- /dev/null
+++ b/tools/tools/ifinfo/Makefile
@@ -0,0 +1,7 @@
+# $Id$
+
+PROG= ifinfo
+SRCS= ifinfo.c rfc1650.c
+NOMAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ifinfo/ifinfo.c b/tools/tools/ifinfo/ifinfo.c
new file mode 100644
index 0000000..14023fa
--- /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 <sys/types.h>
+#include <sys/socket.h> /* for PF_LINK */
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_mib.h>
+
+#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 0000000..24bd476
--- /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 0000000..5347871
--- /dev/null
+++ b/tools/tools/ifinfo/rfc1650.c
@@ -0,0 +1,124 @@
+#include <sys/types.h>
+#include <sys/socket.h> /* for PF_LINK */
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+#include <sysexits.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_mib.h>
+
+#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]);
+}
+
OpenPOWER on IntegriCloud