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