Merge from vendor branch LESS:
[dragonfly.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: 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
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
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
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 *
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 *
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
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
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 }