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