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: #if defined(DOSCCS) && !defined(lint)
14: static char sccsid[] = "@(#)if.c 5.6.1 (2.11BSD GTE) 1/1/94";
15: #endif
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(), *index();
37: #ifdef pdp11
38: #define klseek slseek
39: #endif
40:
41: /*
42: * Print a description of the network interfaces.
43: */
44: intpr(interval, ifnetaddr)
45: int interval;
46: off_t ifnetaddr;
47: {
48: struct ifnet ifnet;
49: union {
50: struct ifaddr ifa;
51: struct in_ifaddr in;
52: } ifaddr;
53: off_t ifaddraddr;
54: char name[16];
55:
56: if (ifnetaddr == 0) {
57: printf("ifnet: symbol not defined\n");
58: return;
59: }
60: if (interval) {
61: sidewaysintpr((unsigned)interval, ifnetaddr);
62: return;
63: }
64: klseek(kmem, ifnetaddr, 0);
65: #ifdef pdp11
66: {
67: unsigned int x;
68: read(kmem, &x, sizeof x);
69: ifnetaddr = (long)x;
70: }
71: #else
72: read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr);
73: #endif
74: printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s",
75: "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
76: "Opkts", "Oerrs");
77: printf(" %5s", "Coll");
78: if (tflag)
79: printf(" %s", "Time");
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: ifaddraddr = (off_t)ifaddr.ifa.ifa_next;
114: switch (ifaddr.ifa.ifa_addr.sa_family) {
115: case AF_UNSPEC:
116: printf("%-11.11s ", "none");
117: printf("%-15.15s ", "none");
118: break;
119: case AF_INET:
120: sin = (struct sockaddr_in *)&ifaddr.in.ia_addr;
121: #ifdef notdef
122: /* can't use inet_makeaddr because kernel
123: * keeps nets unshifted.
124: */
125: in = inet_makeaddr(ifaddr.in.ia_subnet,
126: INADDR_ANY);
127: printf("%-11.11s ", netname(in));
128: #else
129: printf("%-11.11s ",
130: netname(htonl(ifaddr.in.ia_subnet),
131: ifaddr.in.ia_subnetmask));
132: #endif
133: printf("%-15.15s ", routename(sin->sin_addr));
134: break;
135: case AF_NS:
136: {
137: struct sockaddr_ns *sns =
138: (struct sockaddr_ns *)&ifaddr.in.ia_addr;
139: u_long net;
140: char netnum[8];
141: char *ns_phost();
142:
143: *(union ns_net *) &net = sns->sns_addr.x_net;
144: sprintf(netnum, "%lxH", ntohl(net));
145: upHex(netnum);
146: printf("ns:%-8s ", netnum);
147: printf("%-15s ", ns_phost(sns));
148: }
149: break;
150: default:
151: printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family);
152: for (cp = (char *)&ifaddr.ifa.ifa_addr +
153: sizeof(struct sockaddr) - 1;
154: cp >= ifaddr.ifa.ifa_addr.sa_data; --cp)
155: if (*cp != 0)
156: break;
157: n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1;
158: cp = (char *)ifaddr.ifa.ifa_addr.sa_data;
159: if (n <= 7)
160: while (--n)
161: printf("%02d.", *cp++ & 0xff);
162: else
163: while (--n)
164: printf("%02d", *cp++ & 0xff);
165: printf("%02d ", *cp & 0xff);
166: break;
167: }
168: }
169: printf("%8ld %5ld %8ld %5ld %5ld",
170: ifnet.if_ipackets, ifnet.if_ierrors,
171: ifnet.if_opackets, ifnet.if_oerrors,
172: ifnet.if_collisions);
173: if (tflag)
174: printf(" %3d", ifnet.if_timer);
175: putchar('\n');
176: }
177: }
178:
179: #define MAXIF 10
180: struct iftot {
181: char ift_name[16]; /* interface name */
182: long ift_ip; /* input packets */
183: long ift_ie; /* input errors */
184: long ift_op; /* output packets */
185: long ift_oe; /* output errors */
186: long ift_co; /* collisions */
187: } iftot[MAXIF];
188:
189: u_char signalled; /* set if alarm goes off "early" */
190:
191: /*
192: * Print a running summary of interface statistics.
193: * Repeat display every interval seconds, showing statistics
194: * collected over that interval. Assumes that interval is non-zero.
195: * First line printed at top of screen is always cumulative.
196: */
197: sidewaysintpr(interval, off)
198: unsigned interval;
199: off_t off;
200: {
201: struct ifnet ifnet;
202: off_t firstifnet;
203: register struct iftot *ip, *total;
204: register int line;
205: struct iftot *lastif, *sum, *interesting;
206: long oldmask;
207: int catchalarm();
208:
209: klseek(kmem, off, 0);
210: #ifdef pdp11
211: {
212: unsigned int x;
213: read(kmem, &x, sizeof (x));
214: firstifnet = (long)x;
215: }
216: #else
217: read(kmem, (char *)&firstifnet, sizeof (off_t));
218: #endif
219: lastif = iftot;
220: sum = iftot + MAXIF - 1;
221: total = sum - 1;
222: interesting = iftot;
223: for (off = firstifnet, ip = iftot; off;) {
224: char *cp;
225:
226: klseek(kmem, off, 0);
227: read(kmem, (char *)&ifnet, sizeof ifnet);
228: klseek(kmem, (off_t)ifnet.if_name, 0);
229: ip->ift_name[0] = '(';
230: read(kmem, ip->ift_name + 1, 15);
231: if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
232: unit == ifnet.if_unit)
233: interesting = ip;
234: ip->ift_name[15] = '\0';
235: cp = index(ip->ift_name, '\0');
236: sprintf(cp, "%d)", ifnet.if_unit);
237: ip++;
238: if (ip >= iftot + MAXIF - 2)
239: break;
240: off = (off_t) ifnet.if_next;
241: }
242: lastif = ip;
243:
244: (void)signal(SIGALRM, catchalarm);
245: signalled = NO;
246: (void)alarm(interval);
247: banner:
248: printf(" input %-6.6s output ", interesting->ift_name);
249: if (lastif - iftot > 0)
250: printf(" input (Total) output");
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: }
258: putchar('\n');
259: printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
260: "packets", "errs", "packets", "errs", "colls");
261: if (lastif - iftot > 0)
262: printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
263: "packets", "errs", "packets", "errs", "colls");
264: putchar('\n');
265: fflush(stdout);
266: line = 0;
267: loop:
268: sum->ift_ip = 0;
269: sum->ift_ie = 0;
270: sum->ift_op = 0;
271: sum->ift_oe = 0;
272: sum->ift_co = 0;
273: for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
274: klseek(kmem, off, 0);
275: read(kmem, (char *)&ifnet, sizeof ifnet);
276: if (ip == interesting)
277: printf("%8ld %5ld %8ld %5ld %5ld ",
278: ifnet.if_ipackets - ip->ift_ip,
279: ifnet.if_ierrors - ip->ift_ie,
280: ifnet.if_opackets - ip->ift_op,
281: ifnet.if_oerrors - ip->ift_oe,
282: ifnet.if_collisions - ip->ift_co);
283: ip->ift_ip = ifnet.if_ipackets;
284: ip->ift_ie = ifnet.if_ierrors;
285: ip->ift_op = ifnet.if_opackets;
286: ip->ift_oe = ifnet.if_oerrors;
287: ip->ift_co = ifnet.if_collisions;
288: sum->ift_ip += ip->ift_ip;
289: sum->ift_ie += ip->ift_ie;
290: sum->ift_op += ip->ift_op;
291: sum->ift_oe += ip->ift_oe;
292: sum->ift_co += ip->ift_co;
293: off = (off_t) ifnet.if_next;
294: }
295: if (lastif - iftot > 0)
296: printf("%8ld %5ld %8ld %5ld %5ld ",
297: sum->ift_ip - total->ift_ip,
298: sum->ift_ie - total->ift_ie,
299: sum->ift_op - total->ift_op,
300: sum->ift_oe - total->ift_oe,
301: sum->ift_co - total->ift_co);
302: *total = *sum;
303: putchar('\n');
304: fflush(stdout);
305: line++;
306: oldmask = sigblock(sigmask(SIGALRM));
307: if (! signalled) {
308: sigpause(0L);
309: }
310: sigsetmask(oldmask);
311: signalled = NO;
312: (void)alarm(interval);
313: if (line == 21)
314: goto banner;
315: goto loop;
316: /*NOTREACHED*/
317: }
318:
319: /*
320: * Called if an interval expires before sidewaysintpr has completed a loop.
321: * Sets a flag to not wait for the alarm.
322: */
323: catchalarm()
324: {
325: signalled = YES;
326: }