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