ifinfo.c revision 267654
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 * $FreeBSD: releng/9.3/tools/tools/ifinfo/ifinfo.c 189331 2009-03-04 01:31:09Z yongari $
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 <errno.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <sysexits.h>
42#include <unistd.h>
43
44#include <net/if.h>
45#include <net/if_types.h>
46#include <net/if_mib.h>
47
48#include "ifinfo.h"
49
50static void printit(const struct ifmibdata *, const char *);
51static const char *iftype(int);
52static const char *ifphys(int, int);
53static int isit(int, char **, const char *);
54static printfcn findlink(int);
55
56static void
57usage(const char *argv0)
58{
59	fprintf(stderr, "%s: usage:\n\t%s [-l]\n", argv0, argv0);
60	exit(EX_USAGE);
61}
62
63int
64main(int argc, char **argv)
65{
66	int i, maxifno, retval;
67	struct ifmibdata ifmd;
68	int name[6];
69	size_t len;
70	int c;
71	int dolink = 0;
72	void *linkmib;
73	size_t linkmiblen;
74	printfcn pf;
75	char *dname;
76
77	while ((c = getopt(argc, argv, "l")) != -1) {
78		switch(c) {
79		case 'l':
80			dolink = 1;
81			break;
82		default:
83			usage(argv[0]);
84		}
85	}
86
87	retval = 1;
88
89	name[0] = CTL_NET;
90	name[1] = PF_LINK;
91	name[2] = NETLINK_GENERIC;
92	name[3] = IFMIB_SYSTEM;
93	name[4] = IFMIB_IFCOUNT;
94
95	len = sizeof maxifno;
96	if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0)
97		err(EX_OSERR, "sysctl(net.link.generic.system.ifcount)");
98
99	for (i = 1; i <= maxifno; i++) {
100		len = sizeof ifmd;
101		name[3] = IFMIB_IFDATA;
102		name[4] = i;
103		name[5] = IFDATA_GENERAL;
104		if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) {
105			if (errno == ENOENT)
106				continue;
107
108			err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)",
109			    i);
110		}
111
112		if (!isit(argc - optind, argv + optind, ifmd.ifmd_name))
113			continue;
114
115		dname = NULL;
116		len = 0;
117		name[5] = IFDATA_DRIVERNAME;
118		if (sysctl(name, 6, NULL, &len, 0, 0) < 0) {
119			warn("sysctl(net.link.ifdata.%d.drivername)", i);
120		} else {
121			if ((dname = malloc(len)) == NULL)
122				err(EX_OSERR, NULL);
123			if (sysctl(name, 6, dname, &len, 0, 0) < 0) {
124				warn("sysctl(net.link.ifdata.%d.drivername)",
125				    i);
126				free(dname);
127				dname = NULL;
128			}
129		}
130		printit(&ifmd, dname);
131		free(dname);
132		if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) {
133			name[5] = IFDATA_LINKSPECIFIC;
134			if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0)
135				err(EX_OSERR,
136				    "sysctl(net.link.ifdata.%d.linkspec) size",
137				    i);
138			linkmib = malloc(linkmiblen);
139			if (!linkmib)
140				err(EX_OSERR, "malloc(%lu)",
141				    (u_long)linkmiblen);
142			if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0)
143				err(EX_OSERR,
144				    "sysctl(net.link.ifdata.%d.linkspec)",
145				    i);
146			pf(linkmib, linkmiblen);
147			free(linkmib);
148		}
149		retval = 0;
150	}
151
152	return retval;
153}
154
155static void
156printit(const struct ifmibdata *ifmd, const char *dname)
157{
158	printf("Interface %.*s", IFNAMSIZ, ifmd->ifmd_name);
159	if (dname != NULL)
160		printf(" (%s)", dname);
161	printf(":\n");
162	printf("\tflags: %x\n", ifmd->ifmd_flags);
163	printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount);
164	printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len);
165	printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen);
166	printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops);
167	printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type));
168	printf("\tphysical: %s\n", ifphys(ifmd->ifmd_data.ifi_type,
169					  ifmd->ifmd_data.ifi_physical));
170	printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen);
171	printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen);
172	printf("\treceive spare char1: %u\n", ifmd->ifmd_data.ifi_spare_char1);
173	printf("\ttransmit spare char2: %u\n", ifmd->ifmd_data.ifi_spare_char2);
174	printf("\tmtu: %lu\n", ifmd->ifmd_data.ifi_mtu);
175	printf("\tmetric: %lu\n", ifmd->ifmd_data.ifi_metric);
176	printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate);
177	printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets);
178	printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors);
179	printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets);
180	printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors);
181	printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions);
182	printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes);
183	printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes);
184	printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts);
185	printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts);
186	printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops);
187	printf("\tpackets for unknown protocol: %lu\n",
188	       ifmd->ifmd_data.ifi_noproto);
189#ifdef notdef
190	printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming);
191	printf("\ttransmit timing: %lu usec\n",
192	       ifmd->ifmd_data.ifi_xmittiming);
193#endif
194}
195
196static const char *const if_types[] = {
197	"reserved",
198	"other",
199	"BBN 1822",
200	"HDH 1822",
201	"X.25 DDN",
202	"X.25",
203	"Ethernet",
204	"ISO 8802-3 CSMA/CD",
205	"ISO 8802-4 Token Bus",
206	"ISO 8802-5 Token Ring",
207	"ISO 8802-6 DQDB MAN",
208	"StarLAN",
209	"Proteon proNET-10",
210	"Proteon proNET-80",
211	"HyperChannel",
212	"FDDI",
213	"LAP-B",
214	"SDLC",
215	"T-1",
216	"CEPT",
217	"Basic rate ISDN",
218	"Primary rate ISDN",
219	"Proprietary P2P",
220	"PPP",
221	"Loopback",
222	"ISO CLNP over IP",
223	"Experimental Ethernet",
224	"XNS over IP",
225	"SLIP",
226	"Ultra Technologies",
227	"DS-3",
228	"SMDS",
229	"Frame Relay",
230	"RS-232 serial",
231	"Parallel printer port",
232	"ARCNET",
233	"ARCNET+",
234	"ATM",
235	"MIOX25",
236	"SONET/SDH",
237	"X25PLE",
238	"ISO 8802-2 LLC",
239	"LocalTalk",
240	"SMDSDXI",
241	"Frame Relay DCE",
242	"V.35",
243	"HSSI",
244	"HIPPI",
245	"Generic Modem",
246	"ATM AAL5",
247	"SONETPATH",
248	"SONETVT",
249	"SMDS InterCarrier Interface",
250	"Proprietary virtual interface",
251	"Proprietary multiplexing",
252	"Generic tunnel interface",
253	"IPv6-to-IPv4 TCP relay capturing interface",
254	"6to4 tunnel interface"
255};
256#define	NIFTYPES ((sizeof if_types)/(sizeof if_types[0]))
257
258static const char *
259iftype(int type)
260{
261	static char buf[256];
262
263	if (type <= 0 || type >= NIFTYPES) {
264		sprintf(buf, "unknown type %d", type);
265		return buf;
266	}
267
268	return if_types[type];
269}
270
271static const char *
272ifphys(int type, int phys)
273{
274	static char buf[256];
275
276	sprintf(buf, "unknown physical %d", phys);
277	return buf;
278}
279
280static int
281isit(int argc, char **argv, const char *name)
282{
283	if (argc == 0)
284		return 1;
285	for (argc = 0; argv[argc]; argc++) {
286		if (strncmp(argv[argc], name, IFNAMSIZ) == 0)
287			return 1;
288	}
289	return 0;
290}
291
292static printfcn
293findlink(int type)
294{
295	switch(type) {
296	case IFT_ETHER:
297	case IFT_ISO88023:
298	case IFT_STARLAN:
299		return print_1650;
300	}
301
302	return 0;
303}
304