]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/ifinfo/ifinfo.c
zfs: merge openzfs/zfs@e0bd8118d
[FreeBSD/FreeBSD.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 #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
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
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
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 *
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
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
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 }