Deleted Added
full compact
if.c (20078) if.c (20287)
1/*
2 * Copyright (c) 1983, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
36#endif /* not lint */
37
38#include <sys/types.h>
39#include <sys/protosw.h>
40#include <sys/socket.h>
1/*
2 * Copyright (c) 1983, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
36#endif /* not lint */
37
38#include <sys/types.h>
39#include <sys/protosw.h>
40#include <sys/socket.h>
41#include <sys/time.h>
41
42#include <net/if.h>
43#include <net/if_dl.h>
44#include <net/if_types.h>
45#include <netinet/in.h>
46#include <netinet/in_var.h>
47#define KERNEL 1
48#include <netinet/if_ether.h>
49#undef KERNEL
50#include <netipx/ipx.h>
51#include <netipx/ipx_if.h>
52#ifdef NS
53#include <netns/ns.h>
54#include <netns/ns_if.h>
55#endif
56#ifdef ISO
57#include <netiso/iso.h>
58#include <netiso/iso_var.h>
59#endif
60#include <arpa/inet.h>
61
62#include <signal.h>
63#include <stdio.h>
64#include <string.h>
65#include <unistd.h>
66
67#include "netstat.h"
68
69#define YES 1
70#define NO 0
71
72static void sidewaysintpr __P((u_int, u_long));
73static void catchalarm __P((int));
74
75/*
76 * Print a description of the network interfaces.
77 */
78void
79intpr(interval, ifnetaddr)
80 int interval;
81 u_long ifnetaddr;
82{
83 struct ifnet ifnet;
84 union {
85 struct ifaddr ifa;
86 struct in_ifaddr in;
87 struct ipx_ifaddr ipx;
88#ifdef NS
89 struct ns_ifaddr ns;
90#endif
91#ifdef ISO
92 struct iso_ifaddr iso;
93#endif
94 } ifaddr;
95 u_long ifaddraddr;
96 u_long ifaddrfound;
97 u_long ifnetfound;
98 struct sockaddr *sa;
99 char name[32], tname[16];
100
101 if (ifnetaddr == 0) {
102 printf("ifnet: symbol not defined\n");
103 return;
104 }
105 if (interval) {
106 sidewaysintpr((unsigned)interval, ifnetaddr);
107 return;
108 }
109 if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr))
110 return;
111 printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
112 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
113 if (bflag)
114 printf(" %10.10s","Ibytes");
115 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
116 if (bflag)
117 printf(" %10.10s","Obytes");
118 printf(" %5s", "Coll");
119 if (tflag)
120 printf(" %s", "Time");
121 if (dflag)
122 printf(" %s", "Drop");
123 putchar('\n');
124 ifaddraddr = 0;
125 while (ifnetaddr || ifaddraddr) {
126 struct sockaddr_in *sin;
127 register char *cp;
128 int n, m;
129
130 if (ifaddraddr == 0) {
131 ifnetfound = ifnetaddr;
132 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) ||
133 kread((u_long)ifnet.if_name, tname, 16))
134 return;
135 tname[15] = '\0';
136 ifnetaddr = (u_long)ifnet.if_next;
137 snprintf(name, 32, "%s%d", tname, ifnet.if_unit);
138 if (interface != 0 && (strcmp(name, interface) != 0))
139 continue;
140 cp = index(name, '\0');
141 if ((ifnet.if_flags&IFF_UP) == 0)
142 *cp++ = '*';
143 *cp = '\0';
144 ifaddraddr = (u_long)ifnet.if_addrlist;
145 }
146 printf("%-5.5s %-5lu ", name, ifnet.if_mtu);
147 ifaddrfound = ifaddraddr;
148 if (ifaddraddr == 0) {
149 printf("%-13.13s ", "none");
150 printf("%-15.15s ", "none");
151 } else {
152 if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
153 ifaddraddr = 0;
154 continue;
155 }
156#define CP(x) ((char *)(x))
157 cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
158 CP(&ifaddr); sa = (struct sockaddr *)cp;
159 switch (sa->sa_family) {
160 case AF_UNSPEC:
161 printf("%-13.13s ", "none");
162 printf("%-15.15s ", "none");
163 break;
164 case AF_INET:
165 sin = (struct sockaddr_in *)sa;
166#ifdef notdef
167 /* can't use inet_makeaddr because kernel
168 * keeps nets unshifted.
169 */
170 in = inet_makeaddr(ifaddr.in.ia_subnet,
171 INADDR_ANY);
172 printf("%-13.13s ", netname(in.s_addr,
173 ifaddr.in.ia_subnetmask));
174#else
175 printf("%-13.13s ",
176 netname(htonl(ifaddr.in.ia_subnet),
177 ifaddr.in.ia_subnetmask));
178#endif
179 printf("%-15.15s ",
180 routename(sin->sin_addr.s_addr));
181 break;
182 case AF_IPX:
183 {
184 struct sockaddr_ipx *sipx =
185 (struct sockaddr_ipx *)sa;
186 u_long net;
187 char netnum[10];
188
189 *(union ipx_net *) &net = sipx->sipx_addr.x_net;
190 sprintf(netnum, "%lx", ntohl(net));
191 printf("ipx:%-8s ", netnum);
192/* printf("ipx:%-8s ", netname(net, 0L)); */
193 printf("%-15s ",
194 ipx_phost((struct sockaddr *)sipx));
195 }
196 break;
197
198 case AF_APPLETALK:
199 printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
200 printf("%-9.9s ",atalk_print(sa,0x0b) );
201 break;
202#ifdef NS
203 case AF_NS:
204 {
205 struct sockaddr_ns *sns =
206 (struct sockaddr_ns *)sa;
207 u_long net;
208 char netnum[10];
209
210 *(union ns_net *) &net = sns->sns_addr.x_net;
211 sprintf(netnum, "%lxH", ntohl(net));
212 upHex(netnum);
213 printf("ns:%-8s ", netnum);
214 printf("%-15s ",
215 ns_phost((struct sockaddr *)sns));
216 }
217 break;
218#endif
219 case AF_LINK:
220 {
221 struct sockaddr_dl *sdl =
222 (struct sockaddr_dl *)sa;
223 cp = (char *)LLADDR(sdl);
224 n = sdl->sdl_alen;
225 }
226 m = printf("%-11.11s ", "<Link>");
227 goto hexprint;
228 default:
229 m = printf("(%d)", sa->sa_family);
230 for (cp = sa->sa_len + (char *)sa;
231 --cp > sa->sa_data && (*cp == 0);) {}
232 n = cp - sa->sa_data + 1;
233 cp = sa->sa_data;
234 hexprint:
235 while (--n >= 0)
236 m += printf("%02x%c", *cp++ & 0xff,
237 n > 0 ? '.' : ' ');
238 m = 30 - m;
239 while (m-- > 0)
240 putchar(' ');
241 break;
242 }
243 ifaddraddr = (u_long)ifaddr.ifa.ifa_next;
244 }
245 printf("%8lu %5lu ",
246 ifnet.if_ipackets, ifnet.if_ierrors);
247 if (bflag)
248 printf("%10lu ", ifnet.if_ibytes);
249 printf("%8lu %5lu ",
250 ifnet.if_opackets, ifnet.if_oerrors);
251 if (bflag)
252 printf("%10lu ", ifnet.if_obytes);
253 printf("%5lu", ifnet.if_collisions);
254 if (tflag)
255 printf(" %3d", ifnet.if_timer);
256 if (dflag)
257 printf(" %3d", ifnet.if_snd.ifq_drops);
258 putchar('\n');
259 if (aflag && ifaddrfound) {
260 /*
261 * Print family's multicast addresses
262 */
263 switch (sa->sa_family) {
264 case AF_INET:
265 {
266 u_long multiaddr;
267 struct in_multi inm;
268
269 multiaddr = (u_long)ifaddr.in.ia_multiaddrs.lh_first;
270 while (multiaddr != 0) {
271 kread(multiaddr, (char *)&inm,
272 sizeof inm);
273 multiaddr = (u_long)inm.inm_entry.le_next;
274 printf("%23s %s\n", "",
275 routename(inm.inm_addr.s_addr));
276 }
277 break;
278 }
279 case AF_LINK:
280 switch (ifnet.if_type) {
281 case IFT_ETHER:
282 case IFT_FDDI: /*XXX*/
283 {
284 off_t multiaddr;
285 struct arpcom ac;
286 struct ether_multi enm;
287
288 kread(ifnetfound, (char *)&ac, sizeof ac);
289 multiaddr = (u_long)ac.ac_multiaddrs;
290 while (multiaddr != 0) {
291 kread(multiaddr, (char *)&enm,
292 sizeof enm);
293 multiaddr = (u_long)enm.enm_next;
294 printf("%23s %s", "",
295 ether_ntoa(&enm.enm_addrlo));
296 if (bcmp(&enm.enm_addrlo,
297 &enm.enm_addrhi, 6) != 0)
298 printf(" to %s",
299 ether_ntoa(&enm.enm_addrhi));
300 printf("\n");
301 }
302 break;
303 }
304 default:
305 break;
306 }
307 default:
308 break;
309 }
310 }
311 }
312}
313
314#define MAXIF 10
315struct iftot {
316 char ift_name[16]; /* interface name */
317 u_int ift_ip; /* input packets */
318 u_int ift_ie; /* input errors */
319 u_int ift_op; /* output packets */
320 u_int ift_oe; /* output errors */
321 u_int ift_co; /* collisions */
322 u_int ift_dr; /* drops */
323 u_int ift_ib; /* input bytes */
324 u_int ift_ob; /* output bytes */
325} iftot[MAXIF];
326
327u_char signalled; /* set if alarm goes off "early" */
328
329/*
330 * Print a running summary of interface statistics.
331 * Repeat display every interval seconds, showing statistics
332 * collected over that interval. Assumes that interval is non-zero.
333 * First line printed at top of screen is always cumulative.
334 */
335static void
336sidewaysintpr(interval, off)
337 unsigned interval;
338 u_long off;
339{
340 struct ifnet ifnet;
341 u_long firstifnet;
342 register struct iftot *ip, *total;
343 register int line;
344 struct iftot *lastif, *sum, *interesting;
345 int oldmask, first;
346 u_long interesting_off;
347
348 if (kread(off, (char *)&firstifnet, sizeof (u_long)))
349 return;
350 lastif = iftot;
351 sum = iftot + MAXIF - 1;
352 total = sum - 1;
353 interesting = NULL;
354 interesting_off = 0;
355 for (off = firstifnet, ip = iftot; off;) {
356 char name[16], tname[16];
357
358 if (kread(off, (char *)&ifnet, sizeof ifnet))
359 break;
360 if (kread((u_long)ifnet.if_name, tname, 16))
361 break;
362 tname[15] = '\0';
363 snprintf(name, 16, "%s%d", tname, ifnet.if_unit);
364 if (interface && strcmp(name, interface) == 0) {
365 interesting = ip;
366 interesting_off = off;
367 }
368 snprintf(ip->ift_name, 16, "(%s)", name);;
369 ip++;
370 if (ip >= iftot + MAXIF - 2)
371 break;
372 off = (u_long) ifnet.if_next;
373 }
374 lastif = ip;
375
376 (void)signal(SIGALRM, catchalarm);
377 signalled = NO;
378 (void)alarm(interval);
379 for (ip = iftot; ip < iftot + MAXIF; ip++) {
380 ip->ift_ip = 0;
381 ip->ift_ie = 0;
382 ip->ift_ib = 0;
383 ip->ift_op = 0;
384 ip->ift_oe = 0;
385 ip->ift_ob = 0;
386 ip->ift_co = 0;
387 ip->ift_dr = 0;
388 }
389 first = 1;
390banner:
391 printf("%17s %14s %16s", "input",
392 interesting ? interesting->ift_name : "(Total)", "output");
393 putchar('\n');
394 printf("%10s %5s %10s %10s %5s %10s %5s",
395 "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
396 if (dflag)
397 printf(" %5.5s", "drops");
398 putchar('\n');
399 fflush(stdout);
400 line = 0;
401loop:
402 if (interesting != NULL) {
403 ip = interesting;
404 if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) {
405 printf("???\n");
406 exit(1);
407 };
408 if (!first) {
409 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
410 ifnet.if_ipackets - ip->ift_ip,
411 ifnet.if_ierrors - ip->ift_ie,
412 ifnet.if_ibytes - ip->ift_ib,
413 ifnet.if_opackets - ip->ift_op,
414 ifnet.if_oerrors - ip->ift_oe,
415 ifnet.if_obytes - ip->ift_ob,
416 ifnet.if_collisions - ip->ift_co);
417 if (dflag)
418 printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr);
419 }
420 ip->ift_ip = ifnet.if_ipackets;
421 ip->ift_ie = ifnet.if_ierrors;
422 ip->ift_ib = ifnet.if_ibytes;
423 ip->ift_op = ifnet.if_opackets;
424 ip->ift_oe = ifnet.if_oerrors;
425 ip->ift_ob = ifnet.if_obytes;
426 ip->ift_co = ifnet.if_collisions;
427 ip->ift_dr = ifnet.if_snd.ifq_drops;
428 } else {
429 sum->ift_ip = 0;
430 sum->ift_ie = 0;
431 sum->ift_ib = 0;
432 sum->ift_op = 0;
433 sum->ift_oe = 0;
434 sum->ift_ob = 0;
435 sum->ift_co = 0;
436 sum->ift_dr = 0;
437 for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
438 if (kread(off, (char *)&ifnet, sizeof ifnet)) {
439 off = 0;
440 continue;
441 }
442 sum->ift_ip += ifnet.if_ipackets;
443 sum->ift_ie += ifnet.if_ierrors;
444 sum->ift_ib += ifnet.if_ibytes;
445 sum->ift_op += ifnet.if_opackets;
446 sum->ift_oe += ifnet.if_oerrors;
447 sum->ift_ob += ifnet.if_obytes;
448 sum->ift_co += ifnet.if_collisions;
449 sum->ift_dr += ifnet.if_snd.ifq_drops;
450 off = (u_long) ifnet.if_next;
451 }
452 if (!first) {
453 printf("%10u %5u %10u %10u %5u %10u %5u",
454 sum->ift_ip - total->ift_ip,
455 sum->ift_ie - total->ift_ie,
456 sum->ift_ib - total->ift_ib,
457 sum->ift_op - total->ift_op,
458 sum->ift_oe - total->ift_oe,
459 sum->ift_ob - total->ift_ob,
460 sum->ift_co - total->ift_co);
461 if (dflag)
462 printf(" %5u", sum->ift_dr - total->ift_dr);
463 }
464 *total = *sum;
465 }
466 if (!first)
467 putchar('\n');
468 fflush(stdout);
469 oldmask = sigblock(sigmask(SIGALRM));
470 if (! signalled) {
471 sigpause(0);
472 }
473 sigsetmask(oldmask);
474 signalled = NO;
475 (void)alarm(interval);
476 line++;
477 first = 0;
478 if (line == 21)
479 goto banner;
480 else
481 goto loop;
482 /*NOTREACHED*/
483}
484
485/*
486 * Called if an interval expires before sidewaysintpr has completed a loop.
487 * Sets a flag to not wait for the alarm.
488 */
489static void
490catchalarm(signo)
491 int signo;
492{
493 signalled = YES;
494}
42
43#include <net/if.h>
44#include <net/if_dl.h>
45#include <net/if_types.h>
46#include <netinet/in.h>
47#include <netinet/in_var.h>
48#define KERNEL 1
49#include <netinet/if_ether.h>
50#undef KERNEL
51#include <netipx/ipx.h>
52#include <netipx/ipx_if.h>
53#ifdef NS
54#include <netns/ns.h>
55#include <netns/ns_if.h>
56#endif
57#ifdef ISO
58#include <netiso/iso.h>
59#include <netiso/iso_var.h>
60#endif
61#include <arpa/inet.h>
62
63#include <signal.h>
64#include <stdio.h>
65#include <string.h>
66#include <unistd.h>
67
68#include "netstat.h"
69
70#define YES 1
71#define NO 0
72
73static void sidewaysintpr __P((u_int, u_long));
74static void catchalarm __P((int));
75
76/*
77 * Print a description of the network interfaces.
78 */
79void
80intpr(interval, ifnetaddr)
81 int interval;
82 u_long ifnetaddr;
83{
84 struct ifnet ifnet;
85 union {
86 struct ifaddr ifa;
87 struct in_ifaddr in;
88 struct ipx_ifaddr ipx;
89#ifdef NS
90 struct ns_ifaddr ns;
91#endif
92#ifdef ISO
93 struct iso_ifaddr iso;
94#endif
95 } ifaddr;
96 u_long ifaddraddr;
97 u_long ifaddrfound;
98 u_long ifnetfound;
99 struct sockaddr *sa;
100 char name[32], tname[16];
101
102 if (ifnetaddr == 0) {
103 printf("ifnet: symbol not defined\n");
104 return;
105 }
106 if (interval) {
107 sidewaysintpr((unsigned)interval, ifnetaddr);
108 return;
109 }
110 if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr))
111 return;
112 printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
113 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
114 if (bflag)
115 printf(" %10.10s","Ibytes");
116 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
117 if (bflag)
118 printf(" %10.10s","Obytes");
119 printf(" %5s", "Coll");
120 if (tflag)
121 printf(" %s", "Time");
122 if (dflag)
123 printf(" %s", "Drop");
124 putchar('\n');
125 ifaddraddr = 0;
126 while (ifnetaddr || ifaddraddr) {
127 struct sockaddr_in *sin;
128 register char *cp;
129 int n, m;
130
131 if (ifaddraddr == 0) {
132 ifnetfound = ifnetaddr;
133 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) ||
134 kread((u_long)ifnet.if_name, tname, 16))
135 return;
136 tname[15] = '\0';
137 ifnetaddr = (u_long)ifnet.if_next;
138 snprintf(name, 32, "%s%d", tname, ifnet.if_unit);
139 if (interface != 0 && (strcmp(name, interface) != 0))
140 continue;
141 cp = index(name, '\0');
142 if ((ifnet.if_flags&IFF_UP) == 0)
143 *cp++ = '*';
144 *cp = '\0';
145 ifaddraddr = (u_long)ifnet.if_addrlist;
146 }
147 printf("%-5.5s %-5lu ", name, ifnet.if_mtu);
148 ifaddrfound = ifaddraddr;
149 if (ifaddraddr == 0) {
150 printf("%-13.13s ", "none");
151 printf("%-15.15s ", "none");
152 } else {
153 if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
154 ifaddraddr = 0;
155 continue;
156 }
157#define CP(x) ((char *)(x))
158 cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
159 CP(&ifaddr); sa = (struct sockaddr *)cp;
160 switch (sa->sa_family) {
161 case AF_UNSPEC:
162 printf("%-13.13s ", "none");
163 printf("%-15.15s ", "none");
164 break;
165 case AF_INET:
166 sin = (struct sockaddr_in *)sa;
167#ifdef notdef
168 /* can't use inet_makeaddr because kernel
169 * keeps nets unshifted.
170 */
171 in = inet_makeaddr(ifaddr.in.ia_subnet,
172 INADDR_ANY);
173 printf("%-13.13s ", netname(in.s_addr,
174 ifaddr.in.ia_subnetmask));
175#else
176 printf("%-13.13s ",
177 netname(htonl(ifaddr.in.ia_subnet),
178 ifaddr.in.ia_subnetmask));
179#endif
180 printf("%-15.15s ",
181 routename(sin->sin_addr.s_addr));
182 break;
183 case AF_IPX:
184 {
185 struct sockaddr_ipx *sipx =
186 (struct sockaddr_ipx *)sa;
187 u_long net;
188 char netnum[10];
189
190 *(union ipx_net *) &net = sipx->sipx_addr.x_net;
191 sprintf(netnum, "%lx", ntohl(net));
192 printf("ipx:%-8s ", netnum);
193/* printf("ipx:%-8s ", netname(net, 0L)); */
194 printf("%-15s ",
195 ipx_phost((struct sockaddr *)sipx));
196 }
197 break;
198
199 case AF_APPLETALK:
200 printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
201 printf("%-9.9s ",atalk_print(sa,0x0b) );
202 break;
203#ifdef NS
204 case AF_NS:
205 {
206 struct sockaddr_ns *sns =
207 (struct sockaddr_ns *)sa;
208 u_long net;
209 char netnum[10];
210
211 *(union ns_net *) &net = sns->sns_addr.x_net;
212 sprintf(netnum, "%lxH", ntohl(net));
213 upHex(netnum);
214 printf("ns:%-8s ", netnum);
215 printf("%-15s ",
216 ns_phost((struct sockaddr *)sns));
217 }
218 break;
219#endif
220 case AF_LINK:
221 {
222 struct sockaddr_dl *sdl =
223 (struct sockaddr_dl *)sa;
224 cp = (char *)LLADDR(sdl);
225 n = sdl->sdl_alen;
226 }
227 m = printf("%-11.11s ", "<Link>");
228 goto hexprint;
229 default:
230 m = printf("(%d)", sa->sa_family);
231 for (cp = sa->sa_len + (char *)sa;
232 --cp > sa->sa_data && (*cp == 0);) {}
233 n = cp - sa->sa_data + 1;
234 cp = sa->sa_data;
235 hexprint:
236 while (--n >= 0)
237 m += printf("%02x%c", *cp++ & 0xff,
238 n > 0 ? '.' : ' ');
239 m = 30 - m;
240 while (m-- > 0)
241 putchar(' ');
242 break;
243 }
244 ifaddraddr = (u_long)ifaddr.ifa.ifa_next;
245 }
246 printf("%8lu %5lu ",
247 ifnet.if_ipackets, ifnet.if_ierrors);
248 if (bflag)
249 printf("%10lu ", ifnet.if_ibytes);
250 printf("%8lu %5lu ",
251 ifnet.if_opackets, ifnet.if_oerrors);
252 if (bflag)
253 printf("%10lu ", ifnet.if_obytes);
254 printf("%5lu", ifnet.if_collisions);
255 if (tflag)
256 printf(" %3d", ifnet.if_timer);
257 if (dflag)
258 printf(" %3d", ifnet.if_snd.ifq_drops);
259 putchar('\n');
260 if (aflag && ifaddrfound) {
261 /*
262 * Print family's multicast addresses
263 */
264 switch (sa->sa_family) {
265 case AF_INET:
266 {
267 u_long multiaddr;
268 struct in_multi inm;
269
270 multiaddr = (u_long)ifaddr.in.ia_multiaddrs.lh_first;
271 while (multiaddr != 0) {
272 kread(multiaddr, (char *)&inm,
273 sizeof inm);
274 multiaddr = (u_long)inm.inm_entry.le_next;
275 printf("%23s %s\n", "",
276 routename(inm.inm_addr.s_addr));
277 }
278 break;
279 }
280 case AF_LINK:
281 switch (ifnet.if_type) {
282 case IFT_ETHER:
283 case IFT_FDDI: /*XXX*/
284 {
285 off_t multiaddr;
286 struct arpcom ac;
287 struct ether_multi enm;
288
289 kread(ifnetfound, (char *)&ac, sizeof ac);
290 multiaddr = (u_long)ac.ac_multiaddrs;
291 while (multiaddr != 0) {
292 kread(multiaddr, (char *)&enm,
293 sizeof enm);
294 multiaddr = (u_long)enm.enm_next;
295 printf("%23s %s", "",
296 ether_ntoa(&enm.enm_addrlo));
297 if (bcmp(&enm.enm_addrlo,
298 &enm.enm_addrhi, 6) != 0)
299 printf(" to %s",
300 ether_ntoa(&enm.enm_addrhi));
301 printf("\n");
302 }
303 break;
304 }
305 default:
306 break;
307 }
308 default:
309 break;
310 }
311 }
312 }
313}
314
315#define MAXIF 10
316struct iftot {
317 char ift_name[16]; /* interface name */
318 u_int ift_ip; /* input packets */
319 u_int ift_ie; /* input errors */
320 u_int ift_op; /* output packets */
321 u_int ift_oe; /* output errors */
322 u_int ift_co; /* collisions */
323 u_int ift_dr; /* drops */
324 u_int ift_ib; /* input bytes */
325 u_int ift_ob; /* output bytes */
326} iftot[MAXIF];
327
328u_char signalled; /* set if alarm goes off "early" */
329
330/*
331 * Print a running summary of interface statistics.
332 * Repeat display every interval seconds, showing statistics
333 * collected over that interval. Assumes that interval is non-zero.
334 * First line printed at top of screen is always cumulative.
335 */
336static void
337sidewaysintpr(interval, off)
338 unsigned interval;
339 u_long off;
340{
341 struct ifnet ifnet;
342 u_long firstifnet;
343 register struct iftot *ip, *total;
344 register int line;
345 struct iftot *lastif, *sum, *interesting;
346 int oldmask, first;
347 u_long interesting_off;
348
349 if (kread(off, (char *)&firstifnet, sizeof (u_long)))
350 return;
351 lastif = iftot;
352 sum = iftot + MAXIF - 1;
353 total = sum - 1;
354 interesting = NULL;
355 interesting_off = 0;
356 for (off = firstifnet, ip = iftot; off;) {
357 char name[16], tname[16];
358
359 if (kread(off, (char *)&ifnet, sizeof ifnet))
360 break;
361 if (kread((u_long)ifnet.if_name, tname, 16))
362 break;
363 tname[15] = '\0';
364 snprintf(name, 16, "%s%d", tname, ifnet.if_unit);
365 if (interface && strcmp(name, interface) == 0) {
366 interesting = ip;
367 interesting_off = off;
368 }
369 snprintf(ip->ift_name, 16, "(%s)", name);;
370 ip++;
371 if (ip >= iftot + MAXIF - 2)
372 break;
373 off = (u_long) ifnet.if_next;
374 }
375 lastif = ip;
376
377 (void)signal(SIGALRM, catchalarm);
378 signalled = NO;
379 (void)alarm(interval);
380 for (ip = iftot; ip < iftot + MAXIF; ip++) {
381 ip->ift_ip = 0;
382 ip->ift_ie = 0;
383 ip->ift_ib = 0;
384 ip->ift_op = 0;
385 ip->ift_oe = 0;
386 ip->ift_ob = 0;
387 ip->ift_co = 0;
388 ip->ift_dr = 0;
389 }
390 first = 1;
391banner:
392 printf("%17s %14s %16s", "input",
393 interesting ? interesting->ift_name : "(Total)", "output");
394 putchar('\n');
395 printf("%10s %5s %10s %10s %5s %10s %5s",
396 "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
397 if (dflag)
398 printf(" %5.5s", "drops");
399 putchar('\n');
400 fflush(stdout);
401 line = 0;
402loop:
403 if (interesting != NULL) {
404 ip = interesting;
405 if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) {
406 printf("???\n");
407 exit(1);
408 };
409 if (!first) {
410 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
411 ifnet.if_ipackets - ip->ift_ip,
412 ifnet.if_ierrors - ip->ift_ie,
413 ifnet.if_ibytes - ip->ift_ib,
414 ifnet.if_opackets - ip->ift_op,
415 ifnet.if_oerrors - ip->ift_oe,
416 ifnet.if_obytes - ip->ift_ob,
417 ifnet.if_collisions - ip->ift_co);
418 if (dflag)
419 printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr);
420 }
421 ip->ift_ip = ifnet.if_ipackets;
422 ip->ift_ie = ifnet.if_ierrors;
423 ip->ift_ib = ifnet.if_ibytes;
424 ip->ift_op = ifnet.if_opackets;
425 ip->ift_oe = ifnet.if_oerrors;
426 ip->ift_ob = ifnet.if_obytes;
427 ip->ift_co = ifnet.if_collisions;
428 ip->ift_dr = ifnet.if_snd.ifq_drops;
429 } else {
430 sum->ift_ip = 0;
431 sum->ift_ie = 0;
432 sum->ift_ib = 0;
433 sum->ift_op = 0;
434 sum->ift_oe = 0;
435 sum->ift_ob = 0;
436 sum->ift_co = 0;
437 sum->ift_dr = 0;
438 for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
439 if (kread(off, (char *)&ifnet, sizeof ifnet)) {
440 off = 0;
441 continue;
442 }
443 sum->ift_ip += ifnet.if_ipackets;
444 sum->ift_ie += ifnet.if_ierrors;
445 sum->ift_ib += ifnet.if_ibytes;
446 sum->ift_op += ifnet.if_opackets;
447 sum->ift_oe += ifnet.if_oerrors;
448 sum->ift_ob += ifnet.if_obytes;
449 sum->ift_co += ifnet.if_collisions;
450 sum->ift_dr += ifnet.if_snd.ifq_drops;
451 off = (u_long) ifnet.if_next;
452 }
453 if (!first) {
454 printf("%10u %5u %10u %10u %5u %10u %5u",
455 sum->ift_ip - total->ift_ip,
456 sum->ift_ie - total->ift_ie,
457 sum->ift_ib - total->ift_ib,
458 sum->ift_op - total->ift_op,
459 sum->ift_oe - total->ift_oe,
460 sum->ift_ob - total->ift_ob,
461 sum->ift_co - total->ift_co);
462 if (dflag)
463 printf(" %5u", sum->ift_dr - total->ift_dr);
464 }
465 *total = *sum;
466 }
467 if (!first)
468 putchar('\n');
469 fflush(stdout);
470 oldmask = sigblock(sigmask(SIGALRM));
471 if (! signalled) {
472 sigpause(0);
473 }
474 sigsetmask(oldmask);
475 signalled = NO;
476 (void)alarm(interval);
477 line++;
478 first = 0;
479 if (line == 21)
480 goto banner;
481 else
482 goto loop;
483 /*NOTREACHED*/
484}
485
486/*
487 * Called if an interval expires before sidewaysintpr has completed a loop.
488 * Sets a flag to not wait for the alarm.
489 */
490static void
491catchalarm(signo)
492 int signo;
493{
494 signalled = YES;
495}