(By Sklower) Checkpoint Mike's changes before making some of my own
[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 *
87198c0c 5 * %sccs.include.redist.c%
5ff67f98
DF
6 */
7
55bef820 8#ifndef lint
bc0c28c1 9static char sccsid[] = "@(#)if.c 5.15 (Berkeley) %G%";
b36fc510 10#endif /* not lint */
55bef820
SL
11
12#include <sys/types.h>
13#include <sys/socket.h>
44906619 14
55bef820 15#include <net/if.h>
7eeb8bb9 16#include <net/if_dl.h>
44906619 17#include <netinet/in.h>
cab3a575 18#include <netinet/in_var.h>
f1fbb01b 19#include <netns/ns.h>
3e117255 20#include <netns/ns_if.h>
c34ecf77
KS
21#include <netiso/iso.h>
22#include <netiso/iso_var.h>
44906619 23
90cb8200 24#include <stdio.h>
39fef23d
MK
25#include <signal.h>
26
27#define YES 1
28#define NO 0
55bef820 29
55bef820 30extern int tflag;
2ebaad6c 31extern int dflag;
55bef820 32extern int nflag;
79ddba48
EW
33extern char *interface;
34extern int unit;
39fef23d 35extern char *routename(), *netname(), *ns_phost();
bc0c28c1 36char *index();
55bef820
SL
37
38/*
39 * Print a description of the network interfaces.
55bef820
SL
40 */
41intpr(interval, ifnetaddr)
42 int interval;
43 off_t ifnetaddr;
44{
45 struct ifnet ifnet;
cab3a575
MK
46 union {
47 struct ifaddr ifa;
48 struct in_ifaddr in;
3e117255 49 struct ns_ifaddr ns;
c34ecf77 50 struct iso_ifaddr iso;
cab3a575
MK
51 } ifaddr;
52 off_t ifaddraddr;
3e117255 53 struct sockaddr *sa;
55bef820
SL
54 char name[16];
55
56 if (ifnetaddr == 0) {
57 printf("ifnet: symbol not defined\n");
58 return;
59 }
60 if (interval) {
39fef23d 61 sidewaysintpr((unsigned)interval, ifnetaddr);
55bef820
SL
62 return;
63 }
c34ecf77 64 kvm_read(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr);
1ecc0948 65 printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s",
55bef820
SL
66 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
67 "Opkts", "Oerrs");
1ecc0948 68 printf(" %5s", "Coll");
55bef820 69 if (tflag)
1ecc0948 70 printf(" %s", "Time");
2ebaad6c
MK
71 if (dflag)
72 printf(" %s", "Drop");
55bef820 73 putchar('\n');
cab3a575
MK
74 ifaddraddr = 0;
75 while (ifnetaddr || ifaddraddr) {
55bef820
SL
76 struct sockaddr_in *sin;
77 register char *cp;
7eeb8bb9 78 int n, m;
3e117255 79 struct in_addr inet_makeaddr();
55bef820 80
cab3a575 81 if (ifaddraddr == 0) {
c34ecf77
KS
82 kvm_read(ifnetaddr, (char *)&ifnet, sizeof ifnet);
83 kvm_read((off_t)ifnet.if_name, name, 16);
cab3a575
MK
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 }
55bef820 96 printf("%-5.5s %-5d ", name, ifnet.if_mtu);
cab3a575 97 if (ifaddraddr == 0) {
1ecc0948
MK
98 printf("%-11.11s ", "none");
99 printf("%-15.15s ", "none");
cab3a575 100 } else {
c34ecf77 101 kvm_read(ifaddraddr, (char *)&ifaddr, sizeof ifaddr);
3e117255
MT
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) {
cab3a575 106 case AF_UNSPEC:
1ecc0948
MK
107 printf("%-11.11s ", "none");
108 printf("%-15.15s ", "none");
cab3a575
MK
109 break;
110 case AF_INET:
3e117255 111 sin = (struct sockaddr_in *)sa;
cab3a575
MK
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);
1ecc0948 118 printf("%-11.11s ", netname(in));
cab3a575 119#else
1ecc0948 120 printf("%-11.11s ",
cab3a575
MK
121 netname(htonl(ifaddr.in.ia_subnet),
122 ifaddr.in.ia_subnetmask));
123#endif
1ecc0948 124 printf("%-15.15s ", routename(sin->sin_addr));
cab3a575 125 break;
f1fbb01b
KS
126 case AF_NS:
127 {
128 struct sockaddr_ns *sns =
3e117255 129 (struct sockaddr_ns *)sa;
39fef23d 130 u_long net;
1ecc0948 131 char netnum[8];
39fef23d
MK
132 char *ns_phost();
133
2ff355d6 134 *(union ns_net *) &net = sns->sns_addr.x_net;
3e117255 135 sprintf(netnum, "%lxH", ntohl(net));
1ecc0948
MK
136 upHex(netnum);
137 printf("ns:%-8s ", netnum);
138 printf("%-15s ", ns_phost(sns));
f1fbb01b
KS
139 }
140 break;
7eeb8bb9
KS
141 case AF_LINK:
142 {
143 struct sockaddr_dl *sdl =
144 (struct sockaddr_dl *)sa;
80b7fcad
KS
145 cp = (char *)LLADDR(sdl);
146 n = sdl->sdl_alen;
7eeb8bb9 147 }
80b7fcad
KS
148 m = printf("<Link>");
149 goto hexprint;
cab3a575 150 default:
80b7fcad
KS
151 m = printf("(%d)", sa->sa_family);
152 for (cp = sa->sa_len + (char *)sa;
153 --cp > sa->sa_data && (*cp == 0);) {}
3e117255
MT
154 n = cp - sa->sa_data + 1;
155 cp = sa->sa_data;
7eeb8bb9 156 hexprint:
80b7fcad
KS
157 while (--n >= 0)
158 m += printf("%x%c", *cp++ & 0xff,
159 n > 0 ? '.' : ' ');
160 m = 28 - m;
7eeb8bb9
KS
161 while (m-- > 0)
162 putchar(' ');
cab3a575
MK
163 break;
164 }
3e117255 165 ifaddraddr = (off_t)ifaddr.ifa.ifa_next;
cab3a575 166 }
1ecc0948 167 printf("%8d %5d %8d %5d %5d",
55bef820
SL
168 ifnet.if_ipackets, ifnet.if_ierrors,
169 ifnet.if_opackets, ifnet.if_oerrors,
170 ifnet.if_collisions);
171 if (tflag)
1ecc0948 172 printf(" %3d", ifnet.if_timer);
2ebaad6c
MK
173 if (dflag)
174 printf(" %3d", ifnet.if_snd.ifq_drops);
55bef820 175 putchar('\n');
55bef820
SL
176 }
177}
178
90cb8200
SL
179#define MAXIF 10
180struct 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 */
2ebaad6c 187 int ift_dr; /* drops */
90cb8200
SL
188} iftot[MAXIF];
189
39fef23d
MK
190u_char signalled; /* set if alarm goes off "early" */
191
90cb8200
SL
192/*
193 * Print a running summary of interface statistics.
39fef23d
MK
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.
90cb8200 197 */
55bef820 198sidewaysintpr(interval, off)
39fef23d 199 unsigned interval;
55bef820
SL
200 off_t off;
201{
202 struct ifnet ifnet;
90cb8200 203 off_t firstifnet;
90cb8200
SL
204 register struct iftot *ip, *total;
205 register int line;
206 struct iftot *lastif, *sum, *interesting;
39fef23d 207 int oldmask;
bc0c28c1 208 void catchalarm();
55bef820 209
c34ecf77 210 kvm_read(off, (char *)&firstifnet, sizeof (off_t));
90cb8200
SL
211 lastif = iftot;
212 sum = iftot + MAXIF - 1;
213 total = sum - 1;
79ddba48 214 interesting = iftot;
90cb8200
SL
215 for (off = firstifnet, ip = iftot; off;) {
216 char *cp;
55bef820 217
c34ecf77 218 kvm_read(off, (char *)&ifnet, sizeof ifnet);
90cb8200 219 ip->ift_name[0] = '(';
c34ecf77 220 kvm_read((off_t)ifnet.if_name, ip->ift_name + 1, 15);
79ddba48
EW
221 if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
222 unit == ifnet.if_unit)
223 interesting = ip;
90cb8200
SL
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;
39fef23d
MK
233
234 (void)signal(SIGALRM, catchalarm);
235 signalled = NO;
236 (void)alarm(interval);
90cb8200 237banner:
2ebaad6c
MK
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 }
90cb8200
SL
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;
2ebaad6c 250 ip->ift_dr = 0;
90cb8200
SL
251 }
252 putchar('\n');
1ecc0948 253 printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
90cb8200 254 "packets", "errs", "packets", "errs", "colls");
2ebaad6c
MK
255 if (dflag)
256 printf("%5.5s ", "drops");
90cb8200 257 if (lastif - iftot > 0)
2ebaad6c 258 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
90cb8200 259 "packets", "errs", "packets", "errs", "colls");
2ebaad6c
MK
260 if (dflag)
261 printf(" %5.5s", "drops");
90cb8200
SL
262 putchar('\n');
263 fflush(stdout);
264 line = 0;
265loop:
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;
2ebaad6c 271 sum->ift_dr = 0;
90cb8200 272 for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
c34ecf77 273 kvm_read(off, (char *)&ifnet, sizeof ifnet);
2ebaad6c
MK
274 if (ip == interesting) {
275 printf("%8d %5d %8d %5d %5d",
90cb8200
SL
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);
2ebaad6c
MK
281 if (dflag)
282 printf(" %5d",
283 ifnet.if_snd.ifq_drops - ip->ift_dr);
284 }
90cb8200
SL
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;
2ebaad6c 290 ip->ift_dr = ifnet.if_snd.ifq_drops;
90cb8200
SL
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;
2ebaad6c 296 sum->ift_dr += ip->ift_dr;
55bef820
SL
297 off = (off_t) ifnet.if_next;
298 }
2ebaad6c
MK
299 if (lastif - iftot > 0) {
300 printf(" %8d %5d %8d %5d %5d",
90cb8200
SL
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);
2ebaad6c
MK
306 if (dflag)
307 printf(" %5d", sum->ift_dr - total->ift_dr);
308 }
90cb8200 309 *total = *sum;
1ecc0948 310 putchar('\n');
90cb8200
SL
311 fflush(stdout);
312 line++;
39fef23d
MK
313 oldmask = sigblock(sigmask(SIGALRM));
314 if (! signalled) {
315 sigpause(0);
316 }
317 sigsetmask(oldmask);
318 signalled = NO;
319 (void)alarm(interval);
90cb8200
SL
320 if (line == 21)
321 goto banner;
322 goto loop;
323 /*NOTREACHED*/
55bef820 324}
39fef23d
MK
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 */
bc0c28c1 330void
39fef23d
MK
331catchalarm()
332{
333 signalled = YES;
334}