Initial import from FreeBSD RELENG_4:
[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  */
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 <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <sysexits.h>
41 #include <unistd.h>
42
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <net/if_mib.h>
46
47 #include "ifinfo.h"
48
49 static void printit(const struct ifmibdata *);
50 static const char *iftype(int);
51 static const char *ifphys(int, int);
52 static int isit(int, char **, const char *);
53 static printfcn findlink(int);
54
55 static void
56 usage(const char *argv0)
57 {
58         fprintf(stderr, "%s: usage:\n\t%s [-l]\n", argv0, argv0);
59         exit(EX_USAGE);
60 }
61
62 int
63 main(int argc, char **argv)
64 {
65         int i, maxifno, retval;
66         struct ifmibdata ifmd;
67         int name[6];
68         size_t len;
69         int c;
70         int dolink = 0;
71         void *linkmib;
72         size_t linkmiblen;
73         printfcn pf;
74
75         while ((c = getopt(argc, argv, "l")) != -1) {
76                 switch(c) {
77                 case 'l':
78                         dolink = 1;
79                         break;
80                 default:
81                         usage(argv[0]);
82                 }
83         }
84         
85         retval = 1;
86
87         name[0] = CTL_NET;
88         name[1] = PF_LINK;
89         name[2] = NETLINK_GENERIC;
90         name[3] = IFMIB_SYSTEM;
91         name[4] = IFMIB_IFCOUNT;
92
93         len = sizeof maxifno;
94         if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0)
95                 err(EX_OSERR, "sysctl(net.link.generic.system.ifcount)");
96
97         for (i = 1; i <= maxifno; i++) {
98                 len = sizeof ifmd;
99                 name[3] = IFMIB_IFDATA;
100                 name[4] = i;
101                 name[5] = IFDATA_GENERAL;
102                 if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0)
103                         err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)",
104                             i);
105
106                 if (!isit(argc - optind, argv + optind, ifmd.ifmd_name))
107                         continue;
108                 printit(&ifmd);
109                 if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) {
110                         name[5] = IFDATA_LINKSPECIFIC;
111                         if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0)
112                                 err(EX_OSERR, 
113                                     "sysctl(net.link.ifdata.%d.linkspec) size",
114                                     i);
115                         linkmib = malloc(linkmiblen);
116                         if (!linkmib)
117                                 err(EX_OSERR, "malloc(%lu)", 
118                                     (u_long)linkmiblen);
119                         if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0)
120                                 err(EX_OSERR, 
121                                     "sysctl(net.link.ifdata.%d.linkspec)",
122                                     i);
123                         pf(linkmib, linkmiblen);
124                         free(linkmib);
125                 }
126                 retval = 0;
127         }
128
129         return retval;
130 }
131
132 static void
133 printit(const struct ifmibdata *ifmd)
134 {
135         printf("Interface %.*s:\n", IFNAMSIZ, ifmd->ifmd_name);
136         printf("\tflags: %x\n", ifmd->ifmd_flags);
137         printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount);
138         printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len);
139         printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen);
140         printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops);
141         printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type));
142         printf("\tphysical: %s\n", ifphys(ifmd->ifmd_data.ifi_type,
143                                           ifmd->ifmd_data.ifi_physical));
144         printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen);
145         printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen);
146         printf("\treceive quota: %d\n", ifmd->ifmd_data.ifi_recvquota);
147         printf("\ttransmit quota: %d\n", ifmd->ifmd_data.ifi_xmitquota);
148         printf("\tmtu: %lu\n", ifmd->ifmd_data.ifi_mtu);
149         printf("\tmetric: %lu\n", ifmd->ifmd_data.ifi_metric);
150         printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate);
151         printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets);
152         printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors);
153         printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets);
154         printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors);
155         printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions);
156         printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes);
157         printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes);
158         printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts);
159         printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts);
160         printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops);
161         printf("\tpackets for unknown protocol: %lu\n", 
162                ifmd->ifmd_data.ifi_noproto);
163 #ifdef notdef
164         printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming);
165         printf("\ttransmit timing: %lu usec\n", 
166                ifmd->ifmd_data.ifi_xmittiming);
167 #endif
168 }
169
170 static const char *const if_types[] = {
171         "reserved",
172         "other",
173         "BBN 1822",
174         "HDH 1822",
175         "X.25 DDN",
176         "X.25",
177         "Ethernet",
178         "ISO 8802-3 CSMA/CD",
179         "ISO 8802-4 Token Bus",
180         "ISO 8802-5 Token Ring",
181         "ISO 8802-6 DQDB MAN",
182         "StarLAN",
183         "Proteon proNET-10",
184         "Proteon proNET-80",
185         "HyperChannel",
186         "FDDI",
187         "LAP-B",
188         "SDLC",
189         "T-1",
190         "CEPT",
191         "Basic rate ISDN",
192         "Primary rate ISDN",
193         "Proprietary P2P",
194         "PPP",
195         "Loopback",
196         "ISO CLNP over IP",
197         "Experimental Ethernet",
198         "XNS over IP",
199         "SLIP",
200         "Ultra Technologies",
201         "DS-3",
202         "SMDS",
203         "Frame Relay",
204         "RS-232 serial",
205         "Parallel printer port",
206         "ARCNET",
207         "ARCNET+",
208         "ATM",
209         "MIOX25",
210         "SONET/SDH",
211         "X25PLE",
212         "ISO 8802-2 LLC",
213         "LocalTalk",
214         "SMDSDXI",
215         "Frame Relay DCE",
216         "V.35",
217         "HSSI",
218         "HIPPI",
219         "Generic Modem",
220         "ATM AAL5",
221         "SONETPATH",
222         "SONETVT",
223         "SMDS InterCarrier Interface",
224         "Proprietary virtual interface",
225         "Proprietary multiplexing",
226         "Generic tunnel interface",
227         "IPv6-to-IPv4 TCP relay capturing interface",
228         "6to4 tunnel interface"
229 };
230 #define NIFTYPES ((sizeof if_types)/(sizeof if_types[0]))
231
232 static const char *
233 iftype(int type)
234 {
235         static char buf[256];
236
237         if (type <= 0 || type >= NIFTYPES) {
238                 sprintf(buf, "unknown type %d", type);
239                 return buf;
240         }
241
242         return if_types[type];
243 }
244
245 static const char *
246 ifphys(int type, int phys)
247 {
248         static char buf[256];
249
250         sprintf(buf, "unknown physical %d", phys);
251         return buf;
252 }
253
254 static int
255 isit(int argc, char **argv, const char *name)
256 {
257         if (argc == 0)
258                 return 1;
259         for (argc = 0; argv[argc]; argc++) {
260                 if (strncmp(argv[argc], name, IFNAMSIZ) == 0)
261                         return 1;
262         }
263         return 0;
264 }
265
266 static printfcn
267 findlink(int type)
268 {
269         switch(type) {
270         case IFT_ETHER:
271         case IFT_ISO88023:
272         case IFT_STARLAN:
273                 return print_1650;
274         }
275
276         return 0;
277 }