ifinfo.c revision 22988
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 * $Id$ 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 42#include <net/if.h> 43#include <net/if_types.h> 44#include <net/if_mib.h> 45 46#include "ifinfo.h" 47 48static void printit(const struct ifmibdata *); 49static const char *iftype(int); 50static const char *ifphys(int, int); 51static int isit(int, char **, const char *); 52static printfcn findlink(int); 53 54static void 55usage(const char *argv0) 56{ 57 fprintf(stderr, "%s: usage:\n\t%s [-i] [ifnames...]\n", 58 argv0, argv0); 59 exit(EX_USAGE); 60} 61 62int 63main(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 132static void 133printit(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 printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming); 164 printf("\ttransmit timing: %lu usec\n", 165 ifmd->ifmd_data.ifi_xmittiming); 166} 167 168static const char *const if_types[] = { 169 "reserved", 170 "other", 171 "BBN 1822", 172 "HDH 1822", 173 "X.25 DDN", 174 "X.25", 175 "Ethernet", 176 "ISO 8802-3 CSMA/CD", 177 "ISO 8802-4 Token Bus", 178 "ISO 8802-5 Token Ring", 179 "ISO 8802-6 DQDB MAN", 180 "StarLAN", 181 "Proteon proNET-10", 182 "Proteon proNET-80", 183 "HyperChannel", 184 "FDDI", 185 "LAP-B", 186 "SDLC", 187 "T-1", 188 "CEPT", 189 "Basic rate ISDN", 190 "Primary rate ISDN", 191 "Proprietary P2P", 192 "PPP", 193 "Loopback", 194 "ISO CLNP over IP", 195 "Experimental Ethernet", 196 "XNS over IP", 197 "SLIP", 198 "Ultra Technologies", 199 "DS-3", 200 "SMDS", 201 "Frame Relay", 202 "RS-232 serial", 203 "Parallel printer port", 204 "ARCNET", 205 "ARCNET+", 206 "ATM", 207 "MIOX25", 208 "SONET/SDH", 209 "X25PLE", 210 "ISO 8802-2 LLC", 211 "LocalTalk", 212 "SMDSDXI", 213 "Frame Relay DCE", 214 "V.35", 215 "HSSI", 216 "HIPPI", 217 "Generic Modem", 218 "ATM AAL5", 219 "SONETPATH", 220 "SONETVT", 221 "SMDS InterCarrier Interface", 222 "Proprietary virtual interface", 223 "Proprietary multiplexing" 224}; 225#define NIFTYPES ((sizeof if_types)/(sizeof if_types[0])) 226 227static const char * 228iftype(int type) 229{ 230 static char buf[256]; 231 232 if (type <= 0 || type > NIFTYPES) { 233 sprintf(buf, "unknown type %d", type); 234 return buf; 235 } 236 237 return if_types[type]; 238} 239 240static const char * 241ifphys(int type, int phys) 242{ 243 static char buf[256]; 244 245 sprintf(buf, "unknown physical %d", phys); 246 return buf; 247} 248 249static int 250isit(int argc, char **argv, const char *name) 251{ 252 if (argc == 0) 253 return 1; 254 for (argc = 0; argv[argc]; argc++) { 255 if (strncmp(argv[argc], name, IFNAMSIZ) == 0) 256 return 1; 257 } 258 return 0; 259} 260 261static printfcn 262findlink(int type) 263{ 264 switch(type) { 265 case IFT_ETHER: 266 case IFT_ISO88023: 267 case IFT_STARLAN: 268 return print_1650; 269 } 270 271 return 0; 272} 273