1 /* 2 * Copyright (c) 1983, 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)if.c 5.10 (Berkeley) 09/25/89"; 20 #endif /* not lint */ 21 22 #include <sys/types.h> 23 #include <sys/socket.h> 24 25 #include <net/if.h> 26 #include <netinet/in.h> 27 #include <netinet/in_var.h> 28 #include <netns/ns.h> 29 #include <netns/ns_if.h> 30 31 #include <stdio.h> 32 #include <signal.h> 33 34 #define YES 1 35 #define NO 0 36 37 extern int kmem; 38 extern int tflag; 39 extern int dflag; 40 extern int nflag; 41 extern char *interface; 42 extern int unit; 43 extern char *routename(), *netname(), *ns_phost(); 44 45 /* 46 * Print a description of the network interfaces. 47 */ 48 intpr(interval, ifnetaddr) 49 int interval; 50 off_t ifnetaddr; 51 { 52 struct ifnet ifnet; 53 union { 54 struct ifaddr ifa; 55 struct in_ifaddr in; 56 struct ns_ifaddr ns; 57 } ifaddr; 58 off_t ifaddraddr; 59 struct sockaddr *sa; 60 char name[16]; 61 62 if (ifnetaddr == 0) { 63 printf("ifnet: symbol not defined\n"); 64 return; 65 } 66 if (interval) { 67 sidewaysintpr((unsigned)interval, ifnetaddr); 68 return; 69 } 70 klseek(kmem, ifnetaddr, 0); 71 read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 72 printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 73 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 74 "Opkts", "Oerrs"); 75 printf(" %5s", "Coll"); 76 if (tflag) 77 printf(" %s", "Time"); 78 if (dflag) 79 printf(" %s", "Drop"); 80 putchar('\n'); 81 ifaddraddr = 0; 82 while (ifnetaddr || ifaddraddr) { 83 struct sockaddr_in *sin; 84 register char *cp; 85 int n; 86 char *index(); 87 struct in_addr inet_makeaddr(); 88 89 if (ifaddraddr == 0) { 90 klseek(kmem, ifnetaddr, 0); 91 read(kmem, (char *)&ifnet, sizeof ifnet); 92 klseek(kmem, (off_t)ifnet.if_name, 0); 93 read(kmem, name, 16); 94 name[15] = '\0'; 95 ifnetaddr = (off_t) ifnet.if_next; 96 if (interface != 0 && 97 (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 98 continue; 99 cp = index(name, '\0'); 100 *cp++ = ifnet.if_unit + '0'; 101 if ((ifnet.if_flags&IFF_UP) == 0) 102 *cp++ = '*'; 103 *cp = '\0'; 104 ifaddraddr = (off_t)ifnet.if_addrlist; 105 } 106 printf("%-5.5s %-5d ", name, ifnet.if_mtu); 107 if (ifaddraddr == 0) { 108 printf("%-11.11s ", "none"); 109 printf("%-15.15s ", "none"); 110 } else { 111 klseek(kmem, ifaddraddr, 0); 112 read(kmem, (char *)&ifaddr, sizeof ifaddr); 113 #define CP(x) ((char *)(x)) 114 cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 115 CP(&ifaddr); sa = (struct sockaddr *)cp; 116 switch (sa->sa_family) { 117 case AF_UNSPEC: 118 printf("%-11.11s ", "none"); 119 printf("%-15.15s ", "none"); 120 break; 121 case AF_INET: 122 sin = (struct sockaddr_in *)sa; 123 #ifdef notdef 124 /* can't use inet_makeaddr because kernel 125 * keeps nets unshifted. 126 */ 127 in = inet_makeaddr(ifaddr.in.ia_subnet, 128 INADDR_ANY); 129 printf("%-11.11s ", netname(in)); 130 #else 131 printf("%-11.11s ", 132 netname(htonl(ifaddr.in.ia_subnet), 133 ifaddr.in.ia_subnetmask)); 134 #endif 135 printf("%-15.15s ", routename(sin->sin_addr)); 136 break; 137 case AF_NS: 138 { 139 struct sockaddr_ns *sns = 140 (struct sockaddr_ns *)sa; 141 u_long net; 142 char netnum[8]; 143 char *ns_phost(); 144 145 *(union ns_net *) &net = sns->sns_addr.x_net; 146 sprintf(netnum, "%lxH", ntohl(net)); 147 upHex(netnum); 148 printf("ns:%-8s ", netnum); 149 printf("%-15s ", ns_phost(sns)); 150 } 151 break; 152 default: 153 printf("af%2d: ", sa->sa_family); 154 for (cp = sa->sa_data + sa->sa_len; 155 cp >= sa->sa_data; --cp) 156 if (*cp != 0) 157 break; 158 n = cp - sa->sa_data + 1; 159 cp = sa->sa_data; 160 if (n <= 7) 161 while (--n) 162 printf("%02d.", *cp++ & 0xff); 163 else 164 while (--n) 165 printf("%02d", *cp++ & 0xff); 166 printf("%02d ", *cp & 0xff); 167 break; 168 } 169 ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 170 } 171 printf("%8d %5d %8d %5d %5d", 172 ifnet.if_ipackets, ifnet.if_ierrors, 173 ifnet.if_opackets, ifnet.if_oerrors, 174 ifnet.if_collisions); 175 if (tflag) 176 printf(" %3d", ifnet.if_timer); 177 if (dflag) 178 printf(" %3d", ifnet.if_snd.ifq_drops); 179 putchar('\n'); 180 } 181 } 182 183 #define MAXIF 10 184 struct iftot { 185 char ift_name[16]; /* interface name */ 186 int ift_ip; /* input packets */ 187 int ift_ie; /* input errors */ 188 int ift_op; /* output packets */ 189 int ift_oe; /* output errors */ 190 int ift_co; /* collisions */ 191 int ift_dr; /* drops */ 192 } iftot[MAXIF]; 193 194 u_char signalled; /* set if alarm goes off "early" */ 195 196 /* 197 * Print a running summary of interface statistics. 198 * Repeat display every interval seconds, showing statistics 199 * collected over that interval. Assumes that interval is non-zero. 200 * First line printed at top of screen is always cumulative. 201 */ 202 sidewaysintpr(interval, off) 203 unsigned interval; 204 off_t off; 205 { 206 struct ifnet ifnet; 207 off_t firstifnet; 208 register struct iftot *ip, *total; 209 register int line; 210 struct iftot *lastif, *sum, *interesting; 211 int oldmask; 212 int catchalarm(); 213 214 klseek(kmem, off, 0); 215 read(kmem, (char *)&firstifnet, sizeof (off_t)); 216 lastif = iftot; 217 sum = iftot + MAXIF - 1; 218 total = sum - 1; 219 interesting = iftot; 220 for (off = firstifnet, ip = iftot; off;) { 221 char *cp; 222 223 klseek(kmem, off, 0); 224 read(kmem, (char *)&ifnet, sizeof ifnet); 225 klseek(kmem, (off_t)ifnet.if_name, 0); 226 ip->ift_name[0] = '('; 227 read(kmem, ip->ift_name + 1, 15); 228 if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 229 unit == ifnet.if_unit) 230 interesting = ip; 231 ip->ift_name[15] = '\0'; 232 cp = index(ip->ift_name, '\0'); 233 sprintf(cp, "%d)", ifnet.if_unit); 234 ip++; 235 if (ip >= iftot + MAXIF - 2) 236 break; 237 off = (off_t) ifnet.if_next; 238 } 239 lastif = ip; 240 241 (void)signal(SIGALRM, catchalarm); 242 signalled = NO; 243 (void)alarm(interval); 244 banner: 245 printf(" input %-6.6s output ", interesting->ift_name); 246 if (lastif - iftot > 0) { 247 if (dflag) 248 printf(" "); 249 printf(" input (Total) output"); 250 } 251 for (ip = iftot; ip < iftot + MAXIF; ip++) { 252 ip->ift_ip = 0; 253 ip->ift_ie = 0; 254 ip->ift_op = 0; 255 ip->ift_oe = 0; 256 ip->ift_co = 0; 257 ip->ift_dr = 0; 258 } 259 putchar('\n'); 260 printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 261 "packets", "errs", "packets", "errs", "colls"); 262 if (dflag) 263 printf("%5.5s ", "drops"); 264 if (lastif - iftot > 0) 265 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 266 "packets", "errs", "packets", "errs", "colls"); 267 if (dflag) 268 printf(" %5.5s", "drops"); 269 putchar('\n'); 270 fflush(stdout); 271 line = 0; 272 loop: 273 sum->ift_ip = 0; 274 sum->ift_ie = 0; 275 sum->ift_op = 0; 276 sum->ift_oe = 0; 277 sum->ift_co = 0; 278 sum->ift_dr = 0; 279 for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 280 klseek(kmem, off, 0); 281 read(kmem, (char *)&ifnet, sizeof ifnet); 282 if (ip == interesting) { 283 printf("%8d %5d %8d %5d %5d", 284 ifnet.if_ipackets - ip->ift_ip, 285 ifnet.if_ierrors - ip->ift_ie, 286 ifnet.if_opackets - ip->ift_op, 287 ifnet.if_oerrors - ip->ift_oe, 288 ifnet.if_collisions - ip->ift_co); 289 if (dflag) 290 printf(" %5d", 291 ifnet.if_snd.ifq_drops - ip->ift_dr); 292 } 293 ip->ift_ip = ifnet.if_ipackets; 294 ip->ift_ie = ifnet.if_ierrors; 295 ip->ift_op = ifnet.if_opackets; 296 ip->ift_oe = ifnet.if_oerrors; 297 ip->ift_co = ifnet.if_collisions; 298 ip->ift_dr = ifnet.if_snd.ifq_drops; 299 sum->ift_ip += ip->ift_ip; 300 sum->ift_ie += ip->ift_ie; 301 sum->ift_op += ip->ift_op; 302 sum->ift_oe += ip->ift_oe; 303 sum->ift_co += ip->ift_co; 304 sum->ift_dr += ip->ift_dr; 305 off = (off_t) ifnet.if_next; 306 } 307 if (lastif - iftot > 0) { 308 printf(" %8d %5d %8d %5d %5d", 309 sum->ift_ip - total->ift_ip, 310 sum->ift_ie - total->ift_ie, 311 sum->ift_op - total->ift_op, 312 sum->ift_oe - total->ift_oe, 313 sum->ift_co - total->ift_co); 314 if (dflag) 315 printf(" %5d", sum->ift_dr - total->ift_dr); 316 } 317 *total = *sum; 318 putchar('\n'); 319 fflush(stdout); 320 line++; 321 oldmask = sigblock(sigmask(SIGALRM)); 322 if (! signalled) { 323 sigpause(0); 324 } 325 sigsetmask(oldmask); 326 signalled = NO; 327 (void)alarm(interval); 328 if (line == 21) 329 goto banner; 330 goto loop; 331 /*NOTREACHED*/ 332 } 333 334 /* 335 * Called if an interval expires before sidewaysintpr has completed a loop. 336 * Sets a flag to not wait for the alarm. 337 */ 338 catchalarm() 339 { 340 signalled = YES; 341 } 342