1#include <sys/types.h>
2#include <sys/socket.h>		/* for PF_LINK */
3#include <sys/sysctl.h>
4#include <sys/time.h>
5
6#include <err.h>
7#include <stdio.h>
8#include <string.h>
9#include <sysexits.h>
10
11#include <net/if.h>
12#include <net/if_types.h>
13#include <net/if_mib.h>
14
15#include "ifinfo.h"
16
17#define print(msg, var) \
18	if (var) printf("\t" msg ": %lu\n", (u_long)var)
19
20static void identify_chipset(u_int32_t chipset);
21
22void
23print_1650(const void *xmd, size_t len)
24{
25	const struct ifmib_iso_8802_3 *md = xmd;
26
27	if (len != sizeof *md)
28		warnx("cannot interpret %lu bytes of MIB data", (u_long)len);
29
30	identify_chipset(md->dot3StatsEtherChipSet);
31	print("Alignment errors", md->dot3StatsAlignmentErrors);
32	print("FCS errors", md->dot3StatsFCSErrors);
33	print("Single-collision frames", md->dot3StatsSingleCollisionFrames);
34	print("Multiple-collision frames", md->dot3StatsMultipleCollisionFrames);
35	print("SQE (Heartbeat) test errors", md->dot3StatsSQETestErrors);
36	print("Deferred transmissions", md->dot3StatsDeferredTransmissions);
37	print("Late collisions", md->dot3StatsLateCollisions);
38	print("Excessive collisions", md->dot3StatsExcessiveCollisions);
39	print("Internal transmit errors", md->dot3StatsInternalMacTransmitErrors);
40	print("Carrier sense errors", md->dot3StatsCarrierSenseErrors);
41	print("Frame-too-long errors", md->dot3StatsFrameTooLongs);
42	print("Internal receive errors", md->dot3StatsInternalMacReceiveErrors);
43	print("Missed frames", md->dot3StatsMissedFrames);
44#define	cprint(num) print("Packets with " #num " collisions", \
45			  md->dot3StatsCollFrequencies[num - 1])
46	if (md->dot3Compliance >= DOT3COMPLIANCE_COLLS) {
47		cprint(1); cprint(2); cprint(3); cprint(4);
48		cprint(5); cprint(6); cprint(7); cprint(8);
49		cprint(9); cprint(10); cprint(11); cprint(12);
50		cprint(13); cprint(14); cprint(15); cprint(16);
51	}
52	switch(md->dot3Compliance) {
53	case DOT3COMPLIANCE_STATS:
54		printf("\tCompliance: statistics only\n");
55		break;
56	case DOT3COMPLIANCE_COLLS:
57		printf("\tCompliance: statistics and collisions\n");
58		break;
59	}
60}
61
62static const char *const amd[] = {
63	0, "Am7990", "Am79900", "Am79C940"
64};
65
66static const char *const intel[] = {
67	0, "82586", "82596", "82557"
68};
69
70static const char *const national[] = {
71	0, "8390", "Sonic"
72};
73
74static const char *const fujitsu[] = {
75	0, "86950"
76};
77
78static const char *const digital[] = {
79	0, "DC21040", "DC21140", "DC21041", "DC21140A", "DC21142"
80};
81
82static const char *const westerndigital[] = {
83	0, "83C690", "83C790"
84};
85
86#define vendor(name, sets) { name, sets, (sizeof sets)/(sizeof sets[0]) }
87static struct {
88	const char *name;
89	const char *const *chips;
90	size_t len;
91} chipset_names[] = {
92	{ 0 },
93	vendor("AMD", amd),
94	vendor("Intel", intel),
95	{ 0 },
96	vendor("National Semiconductor", national),
97	vendor("Fujitsu", fujitsu),
98	vendor("Digital", digital),
99	vendor("Western Digital", westerndigital)
100};
101
102static void
103identify_chipset(u_int32_t chipset)
104{
105	enum dot3Vendors vendor = DOT3CHIPSET_VENDOR(chipset);
106	u_int part = DOT3CHIPSET_PART(chipset);
107
108	printf("\tChipset: ");
109	if (vendor < 1
110	    || vendor >= (sizeof chipset_names)/(sizeof chipset_names[0])
111	    || !chipset_names[vendor].name) {
112		printf("unknown\n");
113		return;
114	}
115
116	printf("%s ", chipset_names[vendor].name);
117	if (part < 1 || part >= chipset_names[vendor].len) {
118		printf("unknown\n");
119		return;
120	}
121
122	printf("%s\n", chipset_names[vendor].chips[part]);
123}
124
125