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