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$
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
50 static void printit(const struct ifmibdata *, const char *);
51 static const char *iftype(int);
52 static int isit(int, char **, const char *);
53 static printfcn findlink(int);
54
55 static void
usage(const char * argv0)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
main(int argc,char ** argv)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 char *dname;
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 if (errno == ENOENT)
105 continue;
106
107 err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)",
108 i);
109 }
110
111 if (!isit(argc - optind, argv + optind, ifmd.ifmd_name))
112 continue;
113
114 dname = NULL;
115 len = 0;
116 name[5] = IFDATA_DRIVERNAME;
117 if (sysctl(name, 6, NULL, &len, 0, 0) < 0) {
118 warn("sysctl(net.link.ifdata.%d.drivername)", i);
119 } else {
120 if ((dname = malloc(len)) == NULL)
121 err(EX_OSERR, NULL);
122 if (sysctl(name, 6, dname, &len, 0, 0) < 0) {
123 warn("sysctl(net.link.ifdata.%d.drivername)",
124 i);
125 free(dname);
126 dname = NULL;
127 }
128 }
129 printit(&ifmd, dname);
130 free(dname);
131 if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) {
132 name[5] = IFDATA_LINKSPECIFIC;
133 if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0)
134 err(EX_OSERR,
135 "sysctl(net.link.ifdata.%d.linkspec) size",
136 i);
137 linkmib = malloc(linkmiblen);
138 if (!linkmib)
139 err(EX_OSERR, "malloc(%lu)",
140 (u_long)linkmiblen);
141 if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0)
142 err(EX_OSERR,
143 "sysctl(net.link.ifdata.%d.linkspec)",
144 i);
145 pf(linkmib, linkmiblen);
146 free(linkmib);
147 }
148 retval = 0;
149 }
150
151 return retval;
152 }
153
154 static void
printit(const struct ifmibdata * ifmd,const char * dname)155 printit(const struct ifmibdata *ifmd, const char *dname)
156 {
157 printf("Interface %.*s", IFNAMSIZ, ifmd->ifmd_name);
158 if (dname != NULL)
159 printf(" (%s)", dname);
160 printf(":\n");
161 printf("\tflags: %x\n", ifmd->ifmd_flags);
162 printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount);
163 printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len);
164 printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen);
165 printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops);
166 printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type));
167 printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen);
168 printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen);
169 printf("\tlink state: %u\n", ifmd->ifmd_data.ifi_link_state);
170 printf("\tvhid: %u\n", ifmd->ifmd_data.ifi_vhid);
171 printf("\tdatalen: %u\n", ifmd->ifmd_data.ifi_datalen);
172 printf("\tmtu: %u\n", ifmd->ifmd_data.ifi_mtu);
173 printf("\tmetric: %u\n", ifmd->ifmd_data.ifi_metric);
174 printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate);
175 printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets);
176 printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors);
177 printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets);
178 printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors);
179 printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions);
180 printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes);
181 printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes);
182 printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts);
183 printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts);
184 printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops);
185 printf("\tpackets for unknown protocol: %lu\n",
186 ifmd->ifmd_data.ifi_noproto);
187 printf("\tHW offload capabilities: 0x%lx\n",
188 ifmd->ifmd_data.ifi_hwassist);
189 printf("\tuptime at attach or stat reset: %lu\n",
190 ifmd->ifmd_data.ifi_epoch);
191 #ifdef notdef
192 printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming);
193 printf("\ttransmit timing: %lu usec\n",
194 ifmd->ifmd_data.ifi_xmittiming);
195 #endif
196 }
197
198 static const char *const if_types[] = {
199 "reserved",
200 "other",
201 "BBN 1822",
202 "HDH 1822",
203 "X.25 DDN",
204 "X.25",
205 "Ethernet",
206 "ISO 8802-3 CSMA/CD",
207 "ISO 8802-4 Token Bus",
208 "ISO 8802-5 Token Ring",
209 "ISO 8802-6 DQDB MAN",
210 "StarLAN",
211 "Proteon proNET-10",
212 "Proteon proNET-80",
213 "HyperChannel",
214 "FDDI",
215 "LAP-B",
216 "SDLC",
217 "T-1",
218 "CEPT",
219 "Basic rate ISDN",
220 "Primary rate ISDN",
221 "Proprietary P2P",
222 "PPP",
223 "Loopback",
224 "ISO CLNP over IP",
225 "Experimental Ethernet",
226 "XNS over IP",
227 "SLIP",
228 "Ultra Technologies",
229 "DS-3",
230 "SMDS",
231 "Frame Relay",
232 "RS-232 serial",
233 "Parallel printer port",
234 "ARCNET",
235 "ARCNET+",
236 "ATM",
237 "MIOX25",
238 "SONET/SDH",
239 "X25PLE",
240 "ISO 8802-2 LLC",
241 "LocalTalk",
242 "SMDSDXI",
243 "Frame Relay DCE",
244 "V.35",
245 "HSSI",
246 "HIPPI",
247 "Generic Modem",
248 "ATM AAL5",
249 "SONETPATH",
250 "SONETVT",
251 "SMDS InterCarrier Interface",
252 "Proprietary virtual interface",
253 "Proprietary multiplexing",
254 "Generic tunnel interface",
255 "IPv6-to-IPv4 TCP relay capturing interface",
256 "6to4 tunnel interface"
257 };
258 #define NIFTYPES (int)((sizeof if_types)/(sizeof if_types[0]))
259
260 static const char *
iftype(int type)261 iftype(int type)
262 {
263 static char buf[256];
264
265 if (type <= 0 || type >= NIFTYPES) {
266 sprintf(buf, "unknown type %d", type);
267 return buf;
268 }
269
270 return if_types[type];
271 }
272
273 static int
isit(int argc,char ** argv,const char * name)274 isit(int argc, char **argv, const char *name)
275 {
276 if (argc == 0)
277 return 1;
278 for (argc = 0; argv[argc]; argc++) {
279 if (strncmp(argv[argc], name, IFNAMSIZ) == 0)
280 return 1;
281 }
282 return 0;
283 }
284
285 static printfcn
findlink(int type)286 findlink(int type)
287 {
288 switch(type) {
289 case IFT_ETHER:
290 case IFT_ISO88023:
291 case IFT_STARLAN:
292 return print_1650;
293 }
294
295 return 0;
296 }
297