xref: /dragonfly/tools/tools/ifinfo/ifinfo.c (revision 984263bc)
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  */
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 #include <unistd.h>
42 
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <net/if_mib.h>
46 
47 #include "ifinfo.h"
48 
49 static void printit(const struct ifmibdata *);
50 static const char *iftype(int);
51 static const char *ifphys(int, int);
52 static int isit(int, char **, const char *);
53 static printfcn findlink(int);
54 
55 static void
56 usage(const char *argv0)
57 {
58 	fprintf(stderr, "%s: usage:\n\t%s [-l]\n", argv0, argv0);
59 	exit(EX_USAGE);
60 }
61 
62 int
63 main(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 
132 static void
133 printit(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 #ifdef notdef
164 	printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming);
165 	printf("\ttransmit timing: %lu usec\n",
166 	       ifmd->ifmd_data.ifi_xmittiming);
167 #endif
168 }
169 
170 static const char *const if_types[] = {
171 	"reserved",
172 	"other",
173 	"BBN 1822",
174 	"HDH 1822",
175 	"X.25 DDN",
176 	"X.25",
177 	"Ethernet",
178 	"ISO 8802-3 CSMA/CD",
179 	"ISO 8802-4 Token Bus",
180 	"ISO 8802-5 Token Ring",
181 	"ISO 8802-6 DQDB MAN",
182 	"StarLAN",
183 	"Proteon proNET-10",
184 	"Proteon proNET-80",
185 	"HyperChannel",
186 	"FDDI",
187 	"LAP-B",
188 	"SDLC",
189 	"T-1",
190 	"CEPT",
191 	"Basic rate ISDN",
192 	"Primary rate ISDN",
193 	"Proprietary P2P",
194 	"PPP",
195 	"Loopback",
196 	"ISO CLNP over IP",
197 	"Experimental Ethernet",
198 	"XNS over IP",
199 	"SLIP",
200 	"Ultra Technologies",
201 	"DS-3",
202 	"SMDS",
203 	"Frame Relay",
204 	"RS-232 serial",
205 	"Parallel printer port",
206 	"ARCNET",
207 	"ARCNET+",
208 	"ATM",
209 	"MIOX25",
210 	"SONET/SDH",
211 	"X25PLE",
212 	"ISO 8802-2 LLC",
213 	"LocalTalk",
214 	"SMDSDXI",
215 	"Frame Relay DCE",
216 	"V.35",
217 	"HSSI",
218 	"HIPPI",
219 	"Generic Modem",
220 	"ATM AAL5",
221 	"SONETPATH",
222 	"SONETVT",
223 	"SMDS InterCarrier Interface",
224 	"Proprietary virtual interface",
225 	"Proprietary multiplexing",
226 	"Generic tunnel interface",
227 	"IPv6-to-IPv4 TCP relay capturing interface",
228 	"6to4 tunnel interface"
229 };
230 #define	NIFTYPES ((sizeof if_types)/(sizeof if_types[0]))
231 
232 static const char *
233 iftype(int type)
234 {
235 	static char buf[256];
236 
237 	if (type <= 0 || type >= NIFTYPES) {
238 		sprintf(buf, "unknown type %d", type);
239 		return buf;
240 	}
241 
242 	return if_types[type];
243 }
244 
245 static const char *
246 ifphys(int type, int phys)
247 {
248 	static char buf[256];
249 
250 	sprintf(buf, "unknown physical %d", phys);
251 	return buf;
252 }
253 
254 static int
255 isit(int argc, char **argv, const char *name)
256 {
257 	if (argc == 0)
258 		return 1;
259 	for (argc = 0; argv[argc]; argc++) {
260 		if (strncmp(argv[argc], name, IFNAMSIZ) == 0)
261 			return 1;
262 	}
263 	return 0;
264 }
265 
266 static printfcn
267 findlink(int type)
268 {
269 	switch(type) {
270 	case IFT_ETHER:
271 	case IFT_ISO88023:
272 	case IFT_STARLAN:
273 		return print_1650;
274 	}
275 
276 	return 0;
277 }
278