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 #include <sys/types.h>
30 #include <sys/socket.h> /* for PF_LINK */
31 #include <sys/sysctl.h>
32 #include <sys/time.h>
33
34 #include <err.h>
35 #include <errno.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sysexits.h>
40 #include <unistd.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
48 static void printit(const struct ifmibdata *, const char *);
49 static const char *iftype(int);
50 static int isit(int, char **, const char *);
51 static printfcn findlink(int);
52
53 static void
usage(const char * argv0)54 usage(const char *argv0)
55 {
56 fprintf(stderr, "%s: usage:\n\t%s [-l]\n", argv0, argv0);
57 exit(EX_USAGE);
58 }
59
60 int
main(int argc,char ** argv)61 main(int argc, char **argv)
62 {
63 int i, maxifno, retval;
64 struct ifmibdata ifmd;
65 int name[6];
66 size_t len;
67 int c;
68 int dolink = 0;
69 void *linkmib;
70 size_t linkmiblen;
71 printfcn pf;
72 char *dname;
73
74 while ((c = getopt(argc, argv, "l")) != -1) {
75 switch(c) {
76 case 'l':
77 dolink = 1;
78 break;
79 default:
80 usage(argv[0]);
81 }
82 }
83
84 retval = 1;
85
86 name[0] = CTL_NET;
87 name[1] = PF_LINK;
88 name[2] = NETLINK_GENERIC;
89 name[3] = IFMIB_SYSTEM;
90 name[4] = IFMIB_IFCOUNT;
91
92 len = sizeof maxifno;
93 if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0)
94 err(EX_OSERR, "sysctl(net.link.generic.system.ifcount)");
95
96 for (i = 1; i <= maxifno; i++) {
97 len = sizeof ifmd;
98 name[3] = IFMIB_IFDATA;
99 name[4] = i;
100 name[5] = IFDATA_GENERAL;
101 if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) {
102 if (errno == ENOENT)
103 continue;
104
105 err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)",
106 i);
107 }
108
109 if (!isit(argc - optind, argv + optind, ifmd.ifmd_name))
110 continue;
111
112 dname = NULL;
113 len = 0;
114 name[5] = IFDATA_DRIVERNAME;
115 if (sysctl(name, 6, NULL, &len, 0, 0) < 0) {
116 warn("sysctl(net.link.ifdata.%d.drivername)", i);
117 } else {
118 if ((dname = malloc(len)) == NULL)
119 err(EX_OSERR, NULL);
120 if (sysctl(name, 6, dname, &len, 0, 0) < 0) {
121 warn("sysctl(net.link.ifdata.%d.drivername)",
122 i);
123 free(dname);
124 dname = NULL;
125 }
126 }
127 printit(&ifmd, dname);
128 free(dname);
129 if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) {
130 name[5] = IFDATA_LINKSPECIFIC;
131 if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0)
132 err(EX_OSERR,
133 "sysctl(net.link.ifdata.%d.linkspec) size",
134 i);
135 linkmib = malloc(linkmiblen);
136 if (!linkmib)
137 err(EX_OSERR, "malloc(%lu)",
138 (u_long)linkmiblen);
139 if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0)
140 err(EX_OSERR,
141 "sysctl(net.link.ifdata.%d.linkspec)",
142 i);
143 pf(linkmib, linkmiblen);
144 free(linkmib);
145 }
146 retval = 0;
147 }
148
149 return retval;
150 }
151
152 static void
printit(const struct ifmibdata * ifmd,const char * dname)153 printit(const struct ifmibdata *ifmd, const char *dname)
154 {
155 printf("Interface %.*s", IFNAMSIZ, ifmd->ifmd_name);
156 if (dname != NULL)
157 printf(" (%s)", dname);
158 printf(":\n");
159 printf("\tflags: %x\n", ifmd->ifmd_flags);
160 printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount);
161 printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len);
162 printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen);
163 printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops);
164 printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type));
165 printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen);
166 printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen);
167 printf("\tlink state: %u\n", ifmd->ifmd_data.ifi_link_state);
168 printf("\tvhid: %u\n", ifmd->ifmd_data.ifi_vhid);
169 printf("\tdatalen: %u\n", ifmd->ifmd_data.ifi_datalen);
170 printf("\tmtu: %u\n", ifmd->ifmd_data.ifi_mtu);
171 printf("\tmetric: %u\n", ifmd->ifmd_data.ifi_metric);
172 printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate);
173 printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets);
174 printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors);
175 printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets);
176 printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors);
177 printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions);
178 printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes);
179 printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes);
180 printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts);
181 printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts);
182 printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops);
183 printf("\tpackets for unknown protocol: %lu\n",
184 ifmd->ifmd_data.ifi_noproto);
185 printf("\tHW offload capabilities: 0x%lx\n",
186 ifmd->ifmd_data.ifi_hwassist);
187 printf("\tuptime at attach or stat reset: %lu\n",
188 ifmd->ifmd_data.ifi_epoch);
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
196 static 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 (int)((sizeof if_types)/(sizeof if_types[0]))
257
258 static const char *
iftype(int type)259 iftype(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
271 static int
isit(int argc,char ** argv,const char * name)272 isit(int argc, char **argv, const char *name)
273 {
274 if (argc == 0)
275 return 1;
276 for (argc = 0; argv[argc]; argc++) {
277 if (strncmp(argv[argc], name, IFNAMSIZ) == 0)
278 return 1;
279 }
280 return 0;
281 }
282
283 static printfcn
findlink(int type)284 findlink(int type)
285 {
286 switch(type) {
287 case IFT_ETHER:
288 case IFT_ISO88023:
289 case IFT_STARLAN:
290 return print_1650;
291 }
292
293 return 0;
294 }
295