Deleted Added
full compact
if.c (121816) if.c (123030)
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
35/*
36static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
37*/
38static const char rcsid[] =
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
35/*
36static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
37*/
38static const char rcsid[] =
39 "$FreeBSD: head/usr.bin/netstat/if.c 121816 2003-10-31 18:32:15Z brooks $";
39 "$FreeBSD: head/usr.bin/netstat/if.c 123030 2003-11-28 17:34:23Z bms $";
40#endif /* not lint */
41
42#include <sys/types.h>
43#include <sys/protosw.h>
44#include <sys/socket.h>
45#include <sys/sysctl.h>
46#include <sys/time.h>
47
48#include <net/if.h>
49#include <net/if_var.h>
50#include <net/if_dl.h>
51#include <net/if_types.h>
52#include <net/bridge.h>
53#include <net/ethernet.h>
54#include <netinet/in.h>
55#include <netinet/in_var.h>
56#include <netipx/ipx.h>
57#include <netipx/ipx_if.h>
58#include <arpa/inet.h>
59
60#include <signal.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <unistd.h>
65
66#include "netstat.h"
67
68#define YES 1
69#define NO 0
70
71static void sidewaysintpr (u_int, u_long);
72static void catchalarm (int);
73
74#ifdef INET6
75static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */
76static int bdg_done;
77#endif
78
79/* print bridge statistics */
80void
81bdg_stats(u_long dummy __unused, const char *name, int af1 __unused)
82{
83 int i;
84 size_t slen ;
85 struct bdg_stats s ;
86 int mib[4] ;
87
88 slen = sizeof(s);
89
90 mib[0] = CTL_NET ;
91 mib[1] = PF_LINK ;
92 mib[2] = IFT_ETHER ;
93 mib[3] = PF_BDG ;
94 if (sysctl(mib,4, &s,&slen,NULL,0)==-1)
95 return ; /* no bridging */
96#ifdef INET6
97 if (bdg_done != 0)
98 return;
99 else
100 bdg_done = 1;
101#endif
102 printf("-- Bridging statistics (%s) --\n", name) ;
103 printf(
104"Name In Out Forward Drop Bcast Mcast Local Unknown\n");
105 for (i = 0 ; i < 16 ; i++) {
106 if (s.s[i].name[0])
107 printf("%-6s %9ld%9ld%9ld%9ld%9ld%9ld%9ld%9ld\n",
108 s.s[i].name,
109 s.s[i].p_in[(int)BDG_IN],
110 s.s[i].p_in[(int)BDG_OUT],
111 s.s[i].p_in[(int)BDG_FORWARD],
112 s.s[i].p_in[(int)BDG_DROP],
113 s.s[i].p_in[(int)BDG_BCAST],
114 s.s[i].p_in[(int)BDG_MCAST],
115 s.s[i].p_in[(int)BDG_LOCAL],
116 s.s[i].p_in[(int)BDG_UNKNOWN] );
117 }
118}
119
120
121
122
123/*
124 * Display a formatted value, or a '-' in the same space.
125 */
126static void
127show_stat(const char *fmt, int width, u_long value, short showvalue)
128{
129 char newfmt[32];
130
131 /* Construct the format string */
132 if (showvalue) {
133 sprintf(newfmt, "%%%d%s", width, fmt);
134 printf(newfmt, value);
135 } else {
136 sprintf(newfmt, "%%%ds", width);
137 printf(newfmt, "-");
138 }
139}
140
141
142
143/*
144 * Print a description of the network interfaces.
145 */
146void
147intpr(int _interval, u_long ifnetaddr, void (*pfunc)(char *))
148{
149 struct ifnet ifnet;
150 struct ifnethead ifnethead;
151 union {
152 struct ifaddr ifa;
153 struct in_ifaddr in;
154#ifdef INET6
155 struct in6_ifaddr in6;
156#endif
157 struct ipx_ifaddr ipx;
158 } ifaddr;
159 u_long ifaddraddr;
160 u_long ifaddrfound;
161 u_long ifnetfound;
162 u_long opackets;
163 u_long ipackets;
164 u_long obytes;
165 u_long ibytes;
166 u_long oerrors;
167 u_long ierrors;
168 u_long collisions;
169 short timer;
170 int drops;
171 struct sockaddr *sa = NULL;
172 char name[IFNAMSIZ];
173 short network_layer;
174 short link_layer;
175
176 if (ifnetaddr == 0) {
177 printf("ifnet: symbol not defined\n");
178 return;
179 }
180 if (_interval) {
181 sidewaysintpr((unsigned)_interval, ifnetaddr);
182 return;
183 }
184 if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead))
185 return;
186 ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead);
187 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
188 return;
189
190 if (!pfunc) {
40#endif /* not lint */
41
42#include <sys/types.h>
43#include <sys/protosw.h>
44#include <sys/socket.h>
45#include <sys/sysctl.h>
46#include <sys/time.h>
47
48#include <net/if.h>
49#include <net/if_var.h>
50#include <net/if_dl.h>
51#include <net/if_types.h>
52#include <net/bridge.h>
53#include <net/ethernet.h>
54#include <netinet/in.h>
55#include <netinet/in_var.h>
56#include <netipx/ipx.h>
57#include <netipx/ipx_if.h>
58#include <arpa/inet.h>
59
60#include <signal.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <unistd.h>
65
66#include "netstat.h"
67
68#define YES 1
69#define NO 0
70
71static void sidewaysintpr (u_int, u_long);
72static void catchalarm (int);
73
74#ifdef INET6
75static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */
76static int bdg_done;
77#endif
78
79/* print bridge statistics */
80void
81bdg_stats(u_long dummy __unused, const char *name, int af1 __unused)
82{
83 int i;
84 size_t slen ;
85 struct bdg_stats s ;
86 int mib[4] ;
87
88 slen = sizeof(s);
89
90 mib[0] = CTL_NET ;
91 mib[1] = PF_LINK ;
92 mib[2] = IFT_ETHER ;
93 mib[3] = PF_BDG ;
94 if (sysctl(mib,4, &s,&slen,NULL,0)==-1)
95 return ; /* no bridging */
96#ifdef INET6
97 if (bdg_done != 0)
98 return;
99 else
100 bdg_done = 1;
101#endif
102 printf("-- Bridging statistics (%s) --\n", name) ;
103 printf(
104"Name In Out Forward Drop Bcast Mcast Local Unknown\n");
105 for (i = 0 ; i < 16 ; i++) {
106 if (s.s[i].name[0])
107 printf("%-6s %9ld%9ld%9ld%9ld%9ld%9ld%9ld%9ld\n",
108 s.s[i].name,
109 s.s[i].p_in[(int)BDG_IN],
110 s.s[i].p_in[(int)BDG_OUT],
111 s.s[i].p_in[(int)BDG_FORWARD],
112 s.s[i].p_in[(int)BDG_DROP],
113 s.s[i].p_in[(int)BDG_BCAST],
114 s.s[i].p_in[(int)BDG_MCAST],
115 s.s[i].p_in[(int)BDG_LOCAL],
116 s.s[i].p_in[(int)BDG_UNKNOWN] );
117 }
118}
119
120
121
122
123/*
124 * Display a formatted value, or a '-' in the same space.
125 */
126static void
127show_stat(const char *fmt, int width, u_long value, short showvalue)
128{
129 char newfmt[32];
130
131 /* Construct the format string */
132 if (showvalue) {
133 sprintf(newfmt, "%%%d%s", width, fmt);
134 printf(newfmt, value);
135 } else {
136 sprintf(newfmt, "%%%ds", width);
137 printf(newfmt, "-");
138 }
139}
140
141
142
143/*
144 * Print a description of the network interfaces.
145 */
146void
147intpr(int _interval, u_long ifnetaddr, void (*pfunc)(char *))
148{
149 struct ifnet ifnet;
150 struct ifnethead ifnethead;
151 union {
152 struct ifaddr ifa;
153 struct in_ifaddr in;
154#ifdef INET6
155 struct in6_ifaddr in6;
156#endif
157 struct ipx_ifaddr ipx;
158 } ifaddr;
159 u_long ifaddraddr;
160 u_long ifaddrfound;
161 u_long ifnetfound;
162 u_long opackets;
163 u_long ipackets;
164 u_long obytes;
165 u_long ibytes;
166 u_long oerrors;
167 u_long ierrors;
168 u_long collisions;
169 short timer;
170 int drops;
171 struct sockaddr *sa = NULL;
172 char name[IFNAMSIZ];
173 short network_layer;
174 short link_layer;
175
176 if (ifnetaddr == 0) {
177 printf("ifnet: symbol not defined\n");
178 return;
179 }
180 if (_interval) {
181 sidewaysintpr((unsigned)_interval, ifnetaddr);
182 return;
183 }
184 if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead))
185 return;
186 ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead);
187 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
188 return;
189
190 if (!pfunc) {
191 printf("%-5.5s %5.5s %-13.13s %-17.17s %8.8s %5.5s",
192 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
191 if (Wflag)
192 printf("%-7.7s", "Name");
193 else
194 printf("%-5.5s", "Name");
195 printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s",
196 "Mtu", "Network", "Address", "Ipkts", "Ierrs");
193 if (bflag)
194 printf(" %10.10s","Ibytes");
195 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
196 if (bflag)
197 printf(" %10.10s","Obytes");
198 printf(" %5s", "Coll");
199 if (tflag)
200 printf(" %s", "Time");
201 if (dflag)
202 printf(" %s", "Drop");
203 putchar('\n');
204 }
205 ifaddraddr = 0;
206 while (ifnetaddr || ifaddraddr) {
207 struct sockaddr_in *sin;
208#ifdef INET6
209 struct sockaddr_in6 *sin6;
210#endif
211 char *cp;
212 int n, m;
213
214 network_layer = 0;
215 link_layer = 0;
216
217 if (ifaddraddr == 0) {
218 ifnetfound = ifnetaddr;
219 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
220 return;
221 strlcpy(name, ifnet.if_xname, sizeof(name));
222 ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link);
223 if (interface != 0 && (strcmp(name, interface) != 0))
224 continue;
225 cp = index(name, '\0');
226
227 if (pfunc) {
228 (*pfunc)(name);
229 continue;
230 }
231
232 if ((ifnet.if_flags&IFF_UP) == 0)
233 *cp++ = '*';
234 *cp = '\0';
235 ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
236 }
237 ifaddrfound = ifaddraddr;
238
239 /*
240 * Get the interface stats. These may get
241 * overriden below on a per-interface basis.
242 */
243 opackets = ifnet.if_opackets;
244 ipackets = ifnet.if_ipackets;
245 obytes = ifnet.if_obytes;
246 ibytes = ifnet.if_ibytes;
247 oerrors = ifnet.if_oerrors;
248 ierrors = ifnet.if_ierrors;
249 collisions = ifnet.if_collisions;
250 timer = ifnet.if_timer;
251 drops = ifnet.if_snd.ifq_drops;
252
253 if (ifaddraddr == 0) {
197 if (bflag)
198 printf(" %10.10s","Ibytes");
199 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
200 if (bflag)
201 printf(" %10.10s","Obytes");
202 printf(" %5s", "Coll");
203 if (tflag)
204 printf(" %s", "Time");
205 if (dflag)
206 printf(" %s", "Drop");
207 putchar('\n');
208 }
209 ifaddraddr = 0;
210 while (ifnetaddr || ifaddraddr) {
211 struct sockaddr_in *sin;
212#ifdef INET6
213 struct sockaddr_in6 *sin6;
214#endif
215 char *cp;
216 int n, m;
217
218 network_layer = 0;
219 link_layer = 0;
220
221 if (ifaddraddr == 0) {
222 ifnetfound = ifnetaddr;
223 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
224 return;
225 strlcpy(name, ifnet.if_xname, sizeof(name));
226 ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link);
227 if (interface != 0 && (strcmp(name, interface) != 0))
228 continue;
229 cp = index(name, '\0');
230
231 if (pfunc) {
232 (*pfunc)(name);
233 continue;
234 }
235
236 if ((ifnet.if_flags&IFF_UP) == 0)
237 *cp++ = '*';
238 *cp = '\0';
239 ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
240 }
241 ifaddrfound = ifaddraddr;
242
243 /*
244 * Get the interface stats. These may get
245 * overriden below on a per-interface basis.
246 */
247 opackets = ifnet.if_opackets;
248 ipackets = ifnet.if_ipackets;
249 obytes = ifnet.if_obytes;
250 ibytes = ifnet.if_ibytes;
251 oerrors = ifnet.if_oerrors;
252 ierrors = ifnet.if_ierrors;
253 collisions = ifnet.if_collisions;
254 timer = ifnet.if_timer;
255 drops = ifnet.if_snd.ifq_drops;
256
257 if (ifaddraddr == 0) {
254 printf("%-5.5s %5lu ", name, ifnet.if_mtu);
258 if (Wflag)
259 printf("%-7.7s", name);
260 else
261 printf("%-5.5s", name);
262 printf(" %5lu ", ifnet.if_mtu);
255 printf("%-13.13s ", "none");
256 printf("%-17.17s ", "none");
257 } else {
258 if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
259 ifaddraddr = 0;
260 continue;
261 }
262#define CP(x) ((char *)(x))
263 cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
264 CP(&ifaddr);
265 sa = (struct sockaddr *)cp;
266 if (af != AF_UNSPEC && sa->sa_family != af) {
267 ifaddraddr =
268 (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
269 continue;
270 }
263 printf("%-13.13s ", "none");
264 printf("%-17.17s ", "none");
265 } else {
266 if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
267 ifaddraddr = 0;
268 continue;
269 }
270#define CP(x) ((char *)(x))
271 cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
272 CP(&ifaddr);
273 sa = (struct sockaddr *)cp;
274 if (af != AF_UNSPEC && sa->sa_family != af) {
275 ifaddraddr =
276 (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
277 continue;
278 }
271 printf("%-5.5s %5lu ", name, ifnet.if_mtu);
279 if (Wflag)
280 printf("%-7.7s", name);
281 else
282 printf("%-5.5s", name);
283 printf(" %5lu ", ifnet.if_mtu);
272 switch (sa->sa_family) {
273 case AF_UNSPEC:
274 printf("%-13.13s ", "none");
275 printf("%-15.15s ", "none");
276 break;
277 case AF_INET:
278 sin = (struct sockaddr_in *)sa;
279#ifdef notdef
280 /* can't use inet_makeaddr because kernel
281 * keeps nets unshifted.
282 */
283 in = inet_makeaddr(ifaddr.in.ia_subnet,
284 INADDR_ANY);
285 printf("%-13.13s ", netname(in.s_addr,
286 ifaddr.in.ia_subnetmask));
287#else
288 printf("%-13.13s ",
289 netname(htonl(ifaddr.in.ia_subnet),
290 ifaddr.in.ia_subnetmask));
291#endif
292 printf("%-17.17s ",
293 routename(sin->sin_addr.s_addr));
294
295 network_layer = 1;
296 break;
297#ifdef INET6
298 case AF_INET6:
299 sin6 = (struct sockaddr_in6 *)sa;
300 printf("%-13.13s ",
301 netname6(&ifaddr.in6.ia_addr,
302 &ifaddr.in6.ia_prefixmask.sin6_addr));
303 printf("%-17.17s ",
304 inet_ntop(AF_INET6,
305 &sin6->sin6_addr,
306 ntop_buf, sizeof(ntop_buf)));
307
308 network_layer = 1;
309 break;
310#endif /*INET6*/
311 case AF_IPX:
312 {
313 struct sockaddr_ipx *sipx =
314 (struct sockaddr_ipx *)sa;
315 u_long net;
316 char netnum[10];
317
318 *(union ipx_net *) &net = sipx->sipx_addr.x_net;
319 sprintf(netnum, "%lx", (u_long)ntohl(net));
320 printf("ipx:%-8s ", netnum);
321/* printf("ipx:%-8s ", netname(net, 0L)); */
322 printf("%-17s ",
323 ipx_phost((struct sockaddr *)sipx));
324 }
325
326 network_layer = 1;
327 break;
328
329 case AF_APPLETALK:
330 printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
331 printf("%-11.11s ",atalk_print(sa,0x0b) );
332 break;
333 case AF_LINK:
334 {
335 struct sockaddr_dl *sdl =
336 (struct sockaddr_dl *)sa;
337 char linknum[10];
338 cp = (char *)LLADDR(sdl);
339 n = sdl->sdl_alen;
340 sprintf(linknum, "<Link#%d>", sdl->sdl_index);
341 m = printf("%-13.13s ", linknum);
342 }
343 goto hexprint;
344 default:
345 m = printf("(%d)", sa->sa_family);
346 for (cp = sa->sa_len + (char *)sa;
347 --cp > sa->sa_data && (*cp == 0);) {}
348 n = cp - sa->sa_data + 1;
349 cp = sa->sa_data;
350 hexprint:
351 while (--n >= 0)
352 m += printf("%02x%c", *cp++ & 0xff,
353 n > 0 ? ':' : ' ');
354 m = 32 - m;
355 while (m-- > 0)
356 putchar(' ');
357
358 link_layer = 1;
359 break;
360 }
361
362 /*
363 * Fixup the statistics for interfaces that
364 * update stats for their network addresses
365 */
366 if (network_layer) {
367 opackets = ifaddr.in.ia_ifa.if_opackets;
368 ipackets = ifaddr.in.ia_ifa.if_ipackets;
369 obytes = ifaddr.in.ia_ifa.if_obytes;
370 ibytes = ifaddr.in.ia_ifa.if_ibytes;
371 }
372
373 ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
374 }
375
376 show_stat("lu", 8, ipackets, link_layer|network_layer);
377 printf(" ");
378 show_stat("lu", 5, ierrors, link_layer);
379 printf(" ");
380 if (bflag) {
381 show_stat("lu", 10, ibytes, link_layer|network_layer);
382 printf(" ");
383 }
384 show_stat("lu", 8, opackets, link_layer|network_layer);
385 printf(" ");
386 show_stat("lu", 5, oerrors, link_layer);
387 printf(" ");
388 if (bflag) {
389 show_stat("lu", 10, obytes, link_layer|network_layer);
390 printf(" ");
391 }
392 show_stat("lu", 5, collisions, link_layer);
393 if (tflag) {
394 printf(" ");
395 show_stat("d", 3, timer, link_layer);
396 }
397 if (dflag) {
398 printf(" ");
399 show_stat("d", 3, drops, link_layer);
400 }
401 putchar('\n');
402 if (aflag && ifaddrfound) {
403 /*
404 * Print family's multicast addresses
405 */
406 struct ifmultiaddr *multiaddr;
407 struct ifmultiaddr ifma;
408 union {
409 struct sockaddr sa;
410 struct sockaddr_in in;
411#ifdef INET6
412 struct sockaddr_in6 in6;
413#endif /* INET6 */
414 struct sockaddr_dl dl;
415 } msa;
416 const char *fmt;
417
418 TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) {
419 if (kread((u_long)multiaddr, (char *)&ifma,
420 sizeof ifma))
421 break;
422 multiaddr = &ifma;
423 if (kread((u_long)ifma.ifma_addr, (char *)&msa,
424 sizeof msa))
425 break;
426 if (msa.sa.sa_family != sa->sa_family)
427 continue;
428
429 fmt = 0;
430 switch (msa.sa.sa_family) {
431 case AF_INET:
432 fmt = routename(msa.in.sin_addr.s_addr);
433 break;
434#ifdef INET6
435 case AF_INET6:
436 printf("%23s %-19.19s(refs: %d)\n", "",
437 inet_ntop(AF_INET6,
438 &msa.in6.sin6_addr,
439 ntop_buf,
440 sizeof(ntop_buf)),
441 ifma.ifma_refcount);
442 break;
443#endif /* INET6 */
444 case AF_LINK:
445 switch (msa.dl.sdl_type) {
446 case IFT_ETHER:
447 case IFT_FDDI:
448 fmt = ether_ntoa(
449 (struct ether_addr *)
450 LLADDR(&msa.dl));
451 break;
452 }
453 break;
454 }
455 if (fmt)
456 printf("%23s %s\n", "", fmt);
457 }
458 }
459 }
460}
461
462struct iftot {
463 SLIST_ENTRY(iftot) chain;
464 char ift_name[IFNAMSIZ]; /* interface name */
465 u_long ift_ip; /* input packets */
466 u_long ift_ie; /* input errors */
467 u_long ift_op; /* output packets */
468 u_long ift_oe; /* output errors */
469 u_long ift_co; /* collisions */
470 u_int ift_dr; /* drops */
471 u_long ift_ib; /* input bytes */
472 u_long ift_ob; /* output bytes */
473};
474
475u_char signalled; /* set if alarm goes off "early" */
476
477/*
478 * Print a running summary of interface statistics.
479 * Repeat display every interval seconds, showing statistics
480 * collected over that interval. Assumes that interval is non-zero.
481 * First line printed at top of screen is always cumulative.
482 * XXX - should be rewritten to use ifmib(4).
483 */
484static void
485sidewaysintpr(unsigned interval1, u_long off)
486{
487 struct ifnet ifnet;
488 u_long firstifnet;
489 struct ifnethead ifnethead;
490 struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting;
491 int line;
492 int oldmask, first;
493 u_long interesting_off;
494
495 if (kread(off, (char *)&ifnethead, sizeof ifnethead))
496 return;
497 firstifnet = (u_long)TAILQ_FIRST(&ifnethead);
498
499 if ((iftot = malloc(sizeof(struct iftot))) == NULL) {
500 printf("malloc failed\n");
501 exit(1);
502 }
503 memset(iftot, 0, sizeof(struct iftot));
504
505 interesting = NULL;
506 interesting_off = 0;
507 for (off = firstifnet, ip = iftot; off;) {
508 char name[IFNAMSIZ];
509
510 if (kread(off, (char *)&ifnet, sizeof ifnet))
511 break;
512 strlcpy(name, ifnet.if_xname, sizeof(name));
513 if (interface && strcmp(name, interface) == 0) {
514 interesting = ip;
515 interesting_off = off;
516 }
517 snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name);;
518 if ((ipn = malloc(sizeof(struct iftot))) == NULL) {
519 printf("malloc failed\n");
520 exit(1);
521 }
522 memset(ipn, 0, sizeof(struct iftot));
523 SLIST_NEXT(ip, chain) = ipn;
524 ip = ipn;
525 off = (u_long)TAILQ_NEXT(&ifnet, if_link);
526 }
527 if ((total = malloc(sizeof(struct iftot))) == NULL) {
528 printf("malloc failed\n");
529 exit(1);
530 }
531 memset(total, 0, sizeof(struct iftot));
532 if ((sum = malloc(sizeof(struct iftot))) == NULL) {
533 printf("malloc failed\n");
534 exit(1);
535 }
536 memset(sum, 0, sizeof(struct iftot));
537
538 (void)signal(SIGALRM, catchalarm);
539 signalled = NO;
540 (void)alarm(interval1);
541 first = 1;
542banner:
543 printf("%17s %14s %16s", "input",
544 interesting ? interesting->ift_name : "(Total)", "output");
545 putchar('\n');
546 printf("%10s %5s %10s %10s %5s %10s %5s",
547 "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
548 if (dflag)
549 printf(" %5.5s", "drops");
550 putchar('\n');
551 fflush(stdout);
552 line = 0;
553loop:
554 if (interesting != NULL) {
555 ip = interesting;
556 if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) {
557 printf("???\n");
558 exit(1);
559 };
560 if (!first) {
561 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
562 ifnet.if_ipackets - ip->ift_ip,
563 ifnet.if_ierrors - ip->ift_ie,
564 ifnet.if_ibytes - ip->ift_ib,
565 ifnet.if_opackets - ip->ift_op,
566 ifnet.if_oerrors - ip->ift_oe,
567 ifnet.if_obytes - ip->ift_ob,
568 ifnet.if_collisions - ip->ift_co);
569 if (dflag)
570 printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr);
571 }
572 ip->ift_ip = ifnet.if_ipackets;
573 ip->ift_ie = ifnet.if_ierrors;
574 ip->ift_ib = ifnet.if_ibytes;
575 ip->ift_op = ifnet.if_opackets;
576 ip->ift_oe = ifnet.if_oerrors;
577 ip->ift_ob = ifnet.if_obytes;
578 ip->ift_co = ifnet.if_collisions;
579 ip->ift_dr = ifnet.if_snd.ifq_drops;
580 } else {
581 sum->ift_ip = 0;
582 sum->ift_ie = 0;
583 sum->ift_ib = 0;
584 sum->ift_op = 0;
585 sum->ift_oe = 0;
586 sum->ift_ob = 0;
587 sum->ift_co = 0;
588 sum->ift_dr = 0;
589 for (off = firstifnet, ip = iftot;
590 off && SLIST_NEXT(ip, chain) != NULL;
591 ip = SLIST_NEXT(ip, chain)) {
592 if (kread(off, (char *)&ifnet, sizeof ifnet)) {
593 off = 0;
594 continue;
595 }
596 sum->ift_ip += ifnet.if_ipackets;
597 sum->ift_ie += ifnet.if_ierrors;
598 sum->ift_ib += ifnet.if_ibytes;
599 sum->ift_op += ifnet.if_opackets;
600 sum->ift_oe += ifnet.if_oerrors;
601 sum->ift_ob += ifnet.if_obytes;
602 sum->ift_co += ifnet.if_collisions;
603 sum->ift_dr += ifnet.if_snd.ifq_drops;
604 off = (u_long)TAILQ_NEXT(&ifnet, if_link);
605 }
606 if (!first) {
607 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
608 sum->ift_ip - total->ift_ip,
609 sum->ift_ie - total->ift_ie,
610 sum->ift_ib - total->ift_ib,
611 sum->ift_op - total->ift_op,
612 sum->ift_oe - total->ift_oe,
613 sum->ift_ob - total->ift_ob,
614 sum->ift_co - total->ift_co);
615 if (dflag)
616 printf(" %5u", sum->ift_dr - total->ift_dr);
617 }
618 *total = *sum;
619 }
620 if (!first)
621 putchar('\n');
622 fflush(stdout);
623 oldmask = sigblock(sigmask(SIGALRM));
624 if (! signalled) {
625 sigpause(0);
626 }
627 sigsetmask(oldmask);
628 signalled = NO;
629 (void)alarm(interval1);
630 line++;
631 first = 0;
632 if (line == 21)
633 goto banner;
634 else
635 goto loop;
636 /*NOTREACHED*/
637}
638
639/*
640 * Called if an interval expires before sidewaysintpr has completed a loop.
641 * Sets a flag to not wait for the alarm.
642 */
643static void
644catchalarm(int signo __unused)
645{
646 signalled = YES;
647}
284 switch (sa->sa_family) {
285 case AF_UNSPEC:
286 printf("%-13.13s ", "none");
287 printf("%-15.15s ", "none");
288 break;
289 case AF_INET:
290 sin = (struct sockaddr_in *)sa;
291#ifdef notdef
292 /* can't use inet_makeaddr because kernel
293 * keeps nets unshifted.
294 */
295 in = inet_makeaddr(ifaddr.in.ia_subnet,
296 INADDR_ANY);
297 printf("%-13.13s ", netname(in.s_addr,
298 ifaddr.in.ia_subnetmask));
299#else
300 printf("%-13.13s ",
301 netname(htonl(ifaddr.in.ia_subnet),
302 ifaddr.in.ia_subnetmask));
303#endif
304 printf("%-17.17s ",
305 routename(sin->sin_addr.s_addr));
306
307 network_layer = 1;
308 break;
309#ifdef INET6
310 case AF_INET6:
311 sin6 = (struct sockaddr_in6 *)sa;
312 printf("%-13.13s ",
313 netname6(&ifaddr.in6.ia_addr,
314 &ifaddr.in6.ia_prefixmask.sin6_addr));
315 printf("%-17.17s ",
316 inet_ntop(AF_INET6,
317 &sin6->sin6_addr,
318 ntop_buf, sizeof(ntop_buf)));
319
320 network_layer = 1;
321 break;
322#endif /*INET6*/
323 case AF_IPX:
324 {
325 struct sockaddr_ipx *sipx =
326 (struct sockaddr_ipx *)sa;
327 u_long net;
328 char netnum[10];
329
330 *(union ipx_net *) &net = sipx->sipx_addr.x_net;
331 sprintf(netnum, "%lx", (u_long)ntohl(net));
332 printf("ipx:%-8s ", netnum);
333/* printf("ipx:%-8s ", netname(net, 0L)); */
334 printf("%-17s ",
335 ipx_phost((struct sockaddr *)sipx));
336 }
337
338 network_layer = 1;
339 break;
340
341 case AF_APPLETALK:
342 printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
343 printf("%-11.11s ",atalk_print(sa,0x0b) );
344 break;
345 case AF_LINK:
346 {
347 struct sockaddr_dl *sdl =
348 (struct sockaddr_dl *)sa;
349 char linknum[10];
350 cp = (char *)LLADDR(sdl);
351 n = sdl->sdl_alen;
352 sprintf(linknum, "<Link#%d>", sdl->sdl_index);
353 m = printf("%-13.13s ", linknum);
354 }
355 goto hexprint;
356 default:
357 m = printf("(%d)", sa->sa_family);
358 for (cp = sa->sa_len + (char *)sa;
359 --cp > sa->sa_data && (*cp == 0);) {}
360 n = cp - sa->sa_data + 1;
361 cp = sa->sa_data;
362 hexprint:
363 while (--n >= 0)
364 m += printf("%02x%c", *cp++ & 0xff,
365 n > 0 ? ':' : ' ');
366 m = 32 - m;
367 while (m-- > 0)
368 putchar(' ');
369
370 link_layer = 1;
371 break;
372 }
373
374 /*
375 * Fixup the statistics for interfaces that
376 * update stats for their network addresses
377 */
378 if (network_layer) {
379 opackets = ifaddr.in.ia_ifa.if_opackets;
380 ipackets = ifaddr.in.ia_ifa.if_ipackets;
381 obytes = ifaddr.in.ia_ifa.if_obytes;
382 ibytes = ifaddr.in.ia_ifa.if_ibytes;
383 }
384
385 ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
386 }
387
388 show_stat("lu", 8, ipackets, link_layer|network_layer);
389 printf(" ");
390 show_stat("lu", 5, ierrors, link_layer);
391 printf(" ");
392 if (bflag) {
393 show_stat("lu", 10, ibytes, link_layer|network_layer);
394 printf(" ");
395 }
396 show_stat("lu", 8, opackets, link_layer|network_layer);
397 printf(" ");
398 show_stat("lu", 5, oerrors, link_layer);
399 printf(" ");
400 if (bflag) {
401 show_stat("lu", 10, obytes, link_layer|network_layer);
402 printf(" ");
403 }
404 show_stat("lu", 5, collisions, link_layer);
405 if (tflag) {
406 printf(" ");
407 show_stat("d", 3, timer, link_layer);
408 }
409 if (dflag) {
410 printf(" ");
411 show_stat("d", 3, drops, link_layer);
412 }
413 putchar('\n');
414 if (aflag && ifaddrfound) {
415 /*
416 * Print family's multicast addresses
417 */
418 struct ifmultiaddr *multiaddr;
419 struct ifmultiaddr ifma;
420 union {
421 struct sockaddr sa;
422 struct sockaddr_in in;
423#ifdef INET6
424 struct sockaddr_in6 in6;
425#endif /* INET6 */
426 struct sockaddr_dl dl;
427 } msa;
428 const char *fmt;
429
430 TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) {
431 if (kread((u_long)multiaddr, (char *)&ifma,
432 sizeof ifma))
433 break;
434 multiaddr = &ifma;
435 if (kread((u_long)ifma.ifma_addr, (char *)&msa,
436 sizeof msa))
437 break;
438 if (msa.sa.sa_family != sa->sa_family)
439 continue;
440
441 fmt = 0;
442 switch (msa.sa.sa_family) {
443 case AF_INET:
444 fmt = routename(msa.in.sin_addr.s_addr);
445 break;
446#ifdef INET6
447 case AF_INET6:
448 printf("%23s %-19.19s(refs: %d)\n", "",
449 inet_ntop(AF_INET6,
450 &msa.in6.sin6_addr,
451 ntop_buf,
452 sizeof(ntop_buf)),
453 ifma.ifma_refcount);
454 break;
455#endif /* INET6 */
456 case AF_LINK:
457 switch (msa.dl.sdl_type) {
458 case IFT_ETHER:
459 case IFT_FDDI:
460 fmt = ether_ntoa(
461 (struct ether_addr *)
462 LLADDR(&msa.dl));
463 break;
464 }
465 break;
466 }
467 if (fmt)
468 printf("%23s %s\n", "", fmt);
469 }
470 }
471 }
472}
473
474struct iftot {
475 SLIST_ENTRY(iftot) chain;
476 char ift_name[IFNAMSIZ]; /* interface name */
477 u_long ift_ip; /* input packets */
478 u_long ift_ie; /* input errors */
479 u_long ift_op; /* output packets */
480 u_long ift_oe; /* output errors */
481 u_long ift_co; /* collisions */
482 u_int ift_dr; /* drops */
483 u_long ift_ib; /* input bytes */
484 u_long ift_ob; /* output bytes */
485};
486
487u_char signalled; /* set if alarm goes off "early" */
488
489/*
490 * Print a running summary of interface statistics.
491 * Repeat display every interval seconds, showing statistics
492 * collected over that interval. Assumes that interval is non-zero.
493 * First line printed at top of screen is always cumulative.
494 * XXX - should be rewritten to use ifmib(4).
495 */
496static void
497sidewaysintpr(unsigned interval1, u_long off)
498{
499 struct ifnet ifnet;
500 u_long firstifnet;
501 struct ifnethead ifnethead;
502 struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting;
503 int line;
504 int oldmask, first;
505 u_long interesting_off;
506
507 if (kread(off, (char *)&ifnethead, sizeof ifnethead))
508 return;
509 firstifnet = (u_long)TAILQ_FIRST(&ifnethead);
510
511 if ((iftot = malloc(sizeof(struct iftot))) == NULL) {
512 printf("malloc failed\n");
513 exit(1);
514 }
515 memset(iftot, 0, sizeof(struct iftot));
516
517 interesting = NULL;
518 interesting_off = 0;
519 for (off = firstifnet, ip = iftot; off;) {
520 char name[IFNAMSIZ];
521
522 if (kread(off, (char *)&ifnet, sizeof ifnet))
523 break;
524 strlcpy(name, ifnet.if_xname, sizeof(name));
525 if (interface && strcmp(name, interface) == 0) {
526 interesting = ip;
527 interesting_off = off;
528 }
529 snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name);;
530 if ((ipn = malloc(sizeof(struct iftot))) == NULL) {
531 printf("malloc failed\n");
532 exit(1);
533 }
534 memset(ipn, 0, sizeof(struct iftot));
535 SLIST_NEXT(ip, chain) = ipn;
536 ip = ipn;
537 off = (u_long)TAILQ_NEXT(&ifnet, if_link);
538 }
539 if ((total = malloc(sizeof(struct iftot))) == NULL) {
540 printf("malloc failed\n");
541 exit(1);
542 }
543 memset(total, 0, sizeof(struct iftot));
544 if ((sum = malloc(sizeof(struct iftot))) == NULL) {
545 printf("malloc failed\n");
546 exit(1);
547 }
548 memset(sum, 0, sizeof(struct iftot));
549
550 (void)signal(SIGALRM, catchalarm);
551 signalled = NO;
552 (void)alarm(interval1);
553 first = 1;
554banner:
555 printf("%17s %14s %16s", "input",
556 interesting ? interesting->ift_name : "(Total)", "output");
557 putchar('\n');
558 printf("%10s %5s %10s %10s %5s %10s %5s",
559 "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
560 if (dflag)
561 printf(" %5.5s", "drops");
562 putchar('\n');
563 fflush(stdout);
564 line = 0;
565loop:
566 if (interesting != NULL) {
567 ip = interesting;
568 if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) {
569 printf("???\n");
570 exit(1);
571 };
572 if (!first) {
573 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
574 ifnet.if_ipackets - ip->ift_ip,
575 ifnet.if_ierrors - ip->ift_ie,
576 ifnet.if_ibytes - ip->ift_ib,
577 ifnet.if_opackets - ip->ift_op,
578 ifnet.if_oerrors - ip->ift_oe,
579 ifnet.if_obytes - ip->ift_ob,
580 ifnet.if_collisions - ip->ift_co);
581 if (dflag)
582 printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr);
583 }
584 ip->ift_ip = ifnet.if_ipackets;
585 ip->ift_ie = ifnet.if_ierrors;
586 ip->ift_ib = ifnet.if_ibytes;
587 ip->ift_op = ifnet.if_opackets;
588 ip->ift_oe = ifnet.if_oerrors;
589 ip->ift_ob = ifnet.if_obytes;
590 ip->ift_co = ifnet.if_collisions;
591 ip->ift_dr = ifnet.if_snd.ifq_drops;
592 } else {
593 sum->ift_ip = 0;
594 sum->ift_ie = 0;
595 sum->ift_ib = 0;
596 sum->ift_op = 0;
597 sum->ift_oe = 0;
598 sum->ift_ob = 0;
599 sum->ift_co = 0;
600 sum->ift_dr = 0;
601 for (off = firstifnet, ip = iftot;
602 off && SLIST_NEXT(ip, chain) != NULL;
603 ip = SLIST_NEXT(ip, chain)) {
604 if (kread(off, (char *)&ifnet, sizeof ifnet)) {
605 off = 0;
606 continue;
607 }
608 sum->ift_ip += ifnet.if_ipackets;
609 sum->ift_ie += ifnet.if_ierrors;
610 sum->ift_ib += ifnet.if_ibytes;
611 sum->ift_op += ifnet.if_opackets;
612 sum->ift_oe += ifnet.if_oerrors;
613 sum->ift_ob += ifnet.if_obytes;
614 sum->ift_co += ifnet.if_collisions;
615 sum->ift_dr += ifnet.if_snd.ifq_drops;
616 off = (u_long)TAILQ_NEXT(&ifnet, if_link);
617 }
618 if (!first) {
619 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
620 sum->ift_ip - total->ift_ip,
621 sum->ift_ie - total->ift_ie,
622 sum->ift_ib - total->ift_ib,
623 sum->ift_op - total->ift_op,
624 sum->ift_oe - total->ift_oe,
625 sum->ift_ob - total->ift_ob,
626 sum->ift_co - total->ift_co);
627 if (dflag)
628 printf(" %5u", sum->ift_dr - total->ift_dr);
629 }
630 *total = *sum;
631 }
632 if (!first)
633 putchar('\n');
634 fflush(stdout);
635 oldmask = sigblock(sigmask(SIGALRM));
636 if (! signalled) {
637 sigpause(0);
638 }
639 sigsetmask(oldmask);
640 signalled = NO;
641 (void)alarm(interval1);
642 line++;
643 first = 0;
644 if (line == 21)
645 goto banner;
646 else
647 goto loop;
648 /*NOTREACHED*/
649}
650
651/*
652 * Called if an interval expires before sidewaysintpr has completed a loop.
653 * Sets a flag to not wait for the alarm.
654 */
655static void
656catchalarm(int signo __unused)
657{
658 signalled = YES;
659}