ifinfo.c revision 22988
1/*
2 * Copyright 1996 Massachusetts Institute of Technology
3 *
4 * Permission to use, copy, modify, and distribute this software and
5 * its documentation for any purpose and without fee is hereby
6 * granted, provided that both the above copyright notice and this
7 * permission notice appear in all copies, that both the above
8 * copyright notice and this permission notice appear in all
9 * supporting documentation, and that the name of M.I.T. not be used
10 * in advertising or publicity pertaining to distribution of the
11 * software without specific, written prior permission.  M.I.T. makes
12 * no representations about the suitability of this software for any
13 * purpose.  It is provided "as is" without express or implied
14 * warranty.
15 *
16 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
17 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
20 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 *	$Id$
30 */
31#include <sys/types.h>
32#include <sys/socket.h>		/* for PF_LINK */
33#include <sys/sysctl.h>
34#include <sys/time.h>
35
36#include <err.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <sysexits.h>
41
42#include <net/if.h>
43#include <net/if_types.h>
44#include <net/if_mib.h>
45
46#include "ifinfo.h"
47
48static void printit(const struct ifmibdata *);
49static const char *iftype(int);
50static const char *ifphys(int, int);
51static int isit(int, char **, const char *);
52static printfcn findlink(int);
53
54static void
55usage(const char *argv0)
56{
57	fprintf(stderr, "%s: usage:\n\t%s [-i] [ifnames...]\n",
58		argv0, argv0);
59	exit(EX_USAGE);
60}
61
62int
63main(int argc, char **argv)
64{
65	int i, maxifno, retval;
66	struct ifmibdata ifmd;
67	int name[6];
68	size_t len;
69	int c;
70	int dolink = 0;
71	void *linkmib;
72	size_t linkmiblen;
73	printfcn pf;
74
75	while ((c = getopt(argc, argv, "l")) != -1) {
76		switch(c) {
77		case 'l':
78			dolink = 1;
79			break;
80		default:
81			usage(argv[0]);
82		}
83	}
84
85	retval = 1;
86
87	name[0] = CTL_NET;
88	name[1] = PF_LINK;
89	name[2] = NETLINK_GENERIC;
90	name[3] = IFMIB_SYSTEM;
91	name[4] = IFMIB_IFCOUNT;
92
93	len = sizeof maxifno;
94	if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0)
95		err(EX_OSERR, "sysctl(net.link.generic.system.ifcount)");
96
97	for (i = 1; i <= maxifno; i++) {
98		len = sizeof ifmd;
99		name[3] = IFMIB_IFDATA;
100		name[4] = i;
101		name[5] = IFDATA_GENERAL;
102		if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0)
103			err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)",
104			    i);
105
106		if (!isit(argc - optind, argv + optind, ifmd.ifmd_name))
107			continue;
108		printit(&ifmd);
109		if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) {
110			name[5] = IFDATA_LINKSPECIFIC;
111			if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0)
112				err(EX_OSERR,
113				    "sysctl(net.link.ifdata.%d.linkspec) size",
114				    i);
115			linkmib = malloc(linkmiblen);
116			if (!linkmib)
117				err(EX_OSERR, "malloc(%lu)",
118				    (u_long)linkmiblen);
119			if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0)
120				err(EX_OSERR,
121				    "sysctl(net.link.ifdata.%d.linkspec)",
122				    i);
123			pf(linkmib, linkmiblen);
124			free(linkmib);
125		}
126		retval = 0;
127	}
128
129	return retval;
130}
131
132static void
133printit(const struct ifmibdata *ifmd)
134{
135	printf("Interface %.*s:\n", IFNAMSIZ, ifmd->ifmd_name);
136	printf("\tflags: %x\n", ifmd->ifmd_flags);
137	printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount);
138	printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len);
139	printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen);
140	printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops);
141	printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type));
142	printf("\tphysical: %s\n", ifphys(ifmd->ifmd_data.ifi_type,
143					  ifmd->ifmd_data.ifi_physical));
144	printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen);
145	printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen);
146	printf("\treceive quota: %d\n", ifmd->ifmd_data.ifi_recvquota);
147	printf("\ttransmit quota: %d\n", ifmd->ifmd_data.ifi_xmitquota);
148	printf("\tmtu: %lu\n", ifmd->ifmd_data.ifi_mtu);
149	printf("\tmetric: %lu\n", ifmd->ifmd_data.ifi_metric);
150	printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate);
151	printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets);
152	printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors);
153	printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets);
154	printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors);
155	printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions);
156	printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes);
157	printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes);
158	printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts);
159	printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts);
160	printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops);
161	printf("\tpackets for unknown protocol: %lu\n",
162	       ifmd->ifmd_data.ifi_noproto);
163	printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming);
164	printf("\ttransmit timing: %lu usec\n",
165	       ifmd->ifmd_data.ifi_xmittiming);
166}
167
168static const char *const if_types[] = {
169	"reserved",
170	"other",
171	"BBN 1822",
172	"HDH 1822",
173	"X.25 DDN",
174	"X.25",
175	"Ethernet",
176	"ISO 8802-3 CSMA/CD",
177	"ISO 8802-4 Token Bus",
178	"ISO 8802-5 Token Ring",
179	"ISO 8802-6 DQDB MAN",
180	"StarLAN",
181	"Proteon proNET-10",
182	"Proteon proNET-80",
183	"HyperChannel",
184	"FDDI",
185	"LAP-B",
186	"SDLC",
187	"T-1",
188	"CEPT",
189	"Basic rate ISDN",
190	"Primary rate ISDN",
191	"Proprietary P2P",
192	"PPP",
193	"Loopback",
194	"ISO CLNP over IP",
195	"Experimental Ethernet",
196	"XNS over IP",
197	"SLIP",
198	"Ultra Technologies",
199	"DS-3",
200	"SMDS",
201	"Frame Relay",
202	"RS-232 serial",
203	"Parallel printer port",
204	"ARCNET",
205	"ARCNET+",
206	"ATM",
207	"MIOX25",
208	"SONET/SDH",
209	"X25PLE",
210	"ISO 8802-2 LLC",
211	"LocalTalk",
212	"SMDSDXI",
213	"Frame Relay DCE",
214	"V.35",
215	"HSSI",
216	"HIPPI",
217	"Generic Modem",
218	"ATM AAL5",
219	"SONETPATH",
220	"SONETVT",
221	"SMDS InterCarrier Interface",
222	"Proprietary virtual interface",
223	"Proprietary multiplexing"
224};
225#define	NIFTYPES ((sizeof if_types)/(sizeof if_types[0]))
226
227static const char *
228iftype(int type)
229{
230	static char buf[256];
231
232	if (type <= 0 || type > NIFTYPES) {
233		sprintf(buf, "unknown type %d", type);
234		return buf;
235	}
236
237	return if_types[type];
238}
239
240static const char *
241ifphys(int type, int phys)
242{
243	static char buf[256];
244
245	sprintf(buf, "unknown physical %d", phys);
246	return buf;
247}
248
249static int
250isit(int argc, char **argv, const char *name)
251{
252	if (argc == 0)
253		return 1;
254	for (argc = 0; argv[argc]; argc++) {
255		if (strncmp(argv[argc], name, IFNAMSIZ) == 0)
256			return 1;
257	}
258	return 0;
259}
260
261static printfcn
262findlink(int type)
263{
264	switch(type) {
265	case IFT_ETHER:
266	case IFT_ISO88023:
267	case IFT_STARLAN:
268		return print_1650;
269	}
270
271	return 0;
272}
273