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
usage(const char * argv0)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
main(int argc,char ** argv)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
printit(const struct ifmibdata * ifmd)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 *
iftype(int type)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 *
ifphys(int type,int phys)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
isit(int argc,char ** argv,const char * name)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
findlink(int type)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