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$ 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 <errno.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 *, const char *); 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 char *dname; 76 77 while ((c = getopt(argc, argv, "l")) != -1) { 78 switch(c) { 79 case 'l': 80 dolink = 1; 81 break; 82 default: 83 usage(argv[0]); 84 } 85 } 86 87 retval = 1; 88 89 name[0] = CTL_NET; 90 name[1] = PF_LINK; 91 name[2] = NETLINK_GENERIC; 92 name[3] = IFMIB_SYSTEM; 93 name[4] = IFMIB_IFCOUNT; 94 95 len = sizeof maxifno; 96 if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0) 97 err(EX_OSERR, "sysctl(net.link.generic.system.ifcount)"); 98 99 for (i = 1; i <= maxifno; i++) { 100 len = sizeof ifmd; 101 name[3] = IFMIB_IFDATA; 102 name[4] = i; 103 name[5] = IFDATA_GENERAL; 104 if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) { 105 if (errno == ENOENT) 106 continue; 107 108 err(EX_OSERR, "sysctl(net.link.ifdata.%d.general)", 109 i); 110 } 111 112 if (!isit(argc - optind, argv + optind, ifmd.ifmd_name)) 113 continue; 114 115 dname = NULL; 116 len = 0; 117 name[5] = IFDATA_DRIVERNAME; 118 if (sysctl(name, 6, NULL, &len, 0, 0) < 0) { 119 warn("sysctl(net.link.ifdata.%d.drivername)", i); 120 } else { 121 if ((dname = malloc(len)) == NULL) 122 err(EX_OSERR, NULL); 123 if (sysctl(name, 6, dname, &len, 0, 0) < 0) { 124 warn("sysctl(net.link.ifdata.%d.drivername)", 125 i); 126 free(dname); 127 dname = NULL; 128 } 129 } 130 printit(&ifmd, dname); 131 free(dname); 132 if (dolink && (pf = findlink(ifmd.ifmd_data.ifi_type))) { 133 name[5] = IFDATA_LINKSPECIFIC; 134 if (sysctl(name, 6, 0, &linkmiblen, 0, 0) < 0) 135 err(EX_OSERR, 136 "sysctl(net.link.ifdata.%d.linkspec) size", 137 i); 138 linkmib = malloc(linkmiblen); 139 if (!linkmib) 140 err(EX_OSERR, "malloc(%lu)", 141 (u_long)linkmiblen); 142 if (sysctl(name, 6, linkmib, &linkmiblen, 0, 0) < 0) 143 err(EX_OSERR, 144 "sysctl(net.link.ifdata.%d.linkspec)", 145 i); 146 pf(linkmib, linkmiblen); 147 free(linkmib); 148 } 149 retval = 0; 150 } 151 152 return retval; 153 } 154 155 static void 156 printit(const struct ifmibdata *ifmd, const char *dname) 157 { 158 printf("Interface %.*s", IFNAMSIZ, ifmd->ifmd_name); 159 if (dname != NULL) 160 printf(" (%s)", dname); 161 printf(":\n"); 162 printf("\tflags: %x\n", ifmd->ifmd_flags); 163 printf("\tpromiscuous listeners: %d\n", ifmd->ifmd_pcount); 164 printf("\tsend queue length: %d\n", ifmd->ifmd_snd_len); 165 printf("\tsend queue max length: %d\n", ifmd->ifmd_snd_maxlen); 166 printf("\tsend queue drops: %d\n", ifmd->ifmd_snd_drops); 167 printf("\ttype: %s\n", iftype(ifmd->ifmd_data.ifi_type)); 168 printf("\tphysical: %s\n", ifphys(ifmd->ifmd_data.ifi_type, 169 ifmd->ifmd_data.ifi_physical)); 170 printf("\taddress length: %d\n", ifmd->ifmd_data.ifi_addrlen); 171 printf("\theader length: %d\n", ifmd->ifmd_data.ifi_hdrlen); 172 printf("\tlink state: %u\n", ifmd->ifmd_data.ifi_link_state); 173 printf("\tvhid: %u\n", ifmd->ifmd_data.ifi_vhid); 174 printf("\tdatalen: %u\n", ifmd->ifmd_data.ifi_datalen); 175 printf("\tmtu: %lu\n", ifmd->ifmd_data.ifi_mtu); 176 printf("\tmetric: %lu\n", ifmd->ifmd_data.ifi_metric); 177 printf("\tline rate: %lu bit/s\n", ifmd->ifmd_data.ifi_baudrate); 178 printf("\tpackets received: %lu\n", ifmd->ifmd_data.ifi_ipackets); 179 printf("\tinput errors: %lu\n", ifmd->ifmd_data.ifi_ierrors); 180 printf("\tpackets transmitted: %lu\n", ifmd->ifmd_data.ifi_opackets); 181 printf("\toutput errors: %lu\n", ifmd->ifmd_data.ifi_oerrors); 182 printf("\tcollisions: %lu\n", ifmd->ifmd_data.ifi_collisions); 183 printf("\tbytes received: %lu\n", ifmd->ifmd_data.ifi_ibytes); 184 printf("\tbytes transmitted: %lu\n", ifmd->ifmd_data.ifi_obytes); 185 printf("\tmulticasts received: %lu\n", ifmd->ifmd_data.ifi_imcasts); 186 printf("\tmulticasts transmitted: %lu\n", ifmd->ifmd_data.ifi_omcasts); 187 printf("\tinput queue drops: %lu\n", ifmd->ifmd_data.ifi_iqdrops); 188 printf("\tpackets for unknown protocol: %lu\n", 189 ifmd->ifmd_data.ifi_noproto); 190 printf("\tHW offload capabilities: 0x%lx\n", 191 ifmd->ifmd_data.ifi_hwassist); 192 printf("\tuptime at attach or stat reset: %lu\n", 193 ifmd->ifmd_data.ifi_epoch); 194 #ifdef notdef 195 printf("\treceive timing: %lu usec\n", ifmd->ifmd_data.ifi_recvtiming); 196 printf("\ttransmit timing: %lu usec\n", 197 ifmd->ifmd_data.ifi_xmittiming); 198 #endif 199 } 200 201 static const char *const if_types[] = { 202 "reserved", 203 "other", 204 "BBN 1822", 205 "HDH 1822", 206 "X.25 DDN", 207 "X.25", 208 "Ethernet", 209 "ISO 8802-3 CSMA/CD", 210 "ISO 8802-4 Token Bus", 211 "ISO 8802-5 Token Ring", 212 "ISO 8802-6 DQDB MAN", 213 "StarLAN", 214 "Proteon proNET-10", 215 "Proteon proNET-80", 216 "HyperChannel", 217 "FDDI", 218 "LAP-B", 219 "SDLC", 220 "T-1", 221 "CEPT", 222 "Basic rate ISDN", 223 "Primary rate ISDN", 224 "Proprietary P2P", 225 "PPP", 226 "Loopback", 227 "ISO CLNP over IP", 228 "Experimental Ethernet", 229 "XNS over IP", 230 "SLIP", 231 "Ultra Technologies", 232 "DS-3", 233 "SMDS", 234 "Frame Relay", 235 "RS-232 serial", 236 "Parallel printer port", 237 "ARCNET", 238 "ARCNET+", 239 "ATM", 240 "MIOX25", 241 "SONET/SDH", 242 "X25PLE", 243 "ISO 8802-2 LLC", 244 "LocalTalk", 245 "SMDSDXI", 246 "Frame Relay DCE", 247 "V.35", 248 "HSSI", 249 "HIPPI", 250 "Generic Modem", 251 "ATM AAL5", 252 "SONETPATH", 253 "SONETVT", 254 "SMDS InterCarrier Interface", 255 "Proprietary virtual interface", 256 "Proprietary multiplexing", 257 "Generic tunnel interface", 258 "IPv6-to-IPv4 TCP relay capturing interface", 259 "6to4 tunnel interface" 260 }; 261 #define NIFTYPES ((sizeof if_types)/(sizeof if_types[0])) 262 263 static const char * 264 iftype(int type) 265 { 266 static char buf[256]; 267 268 if (type <= 0 || type >= NIFTYPES) { 269 sprintf(buf, "unknown type %d", type); 270 return buf; 271 } 272 273 return if_types[type]; 274 } 275 276 static const char * 277 ifphys(int type, int phys) 278 { 279 static char buf[256]; 280 281 sprintf(buf, "unknown physical %d", phys); 282 return buf; 283 } 284 285 static int 286 isit(int argc, char **argv, const char *name) 287 { 288 if (argc == 0) 289 return 1; 290 for (argc = 0; argv[argc]; argc++) { 291 if (strncmp(argv[argc], name, IFNAMSIZ) == 0) 292 return 1; 293 } 294 return 0; 295 } 296 297 static printfcn 298 findlink(int type) 299 { 300 switch(type) { 301 case IFT_ETHER: 302 case IFT_ISO88023: 303 case IFT_STARLAN: 304 return print_1650; 305 } 306 307 return 0; 308 } 309