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