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 } 278