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