File: | src/usr.bin/netstat/if.c |
Warning: | line 193, column 31 Access to field 'ifi_mtu' results in a dereference of an undefined pointer value (loaded from variable 'ifd') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: if.c,v 1.78 2021/11/29 06:39:23 deraadt Exp $ */ | |||
2 | /* $NetBSD: if.c,v 1.16.4.2 1996/06/07 21:46:46 thorpej Exp $ */ | |||
3 | ||||
4 | /* | |||
5 | * Copyright (c) 1983, 1988, 1993 | |||
6 | * The Regents of the University of California. All rights reserved. | |||
7 | * | |||
8 | * Redistribution and use in source and binary forms, with or without | |||
9 | * modification, are permitted provided that the following conditions | |||
10 | * are met: | |||
11 | * 1. Redistributions of source code must retain the above copyright | |||
12 | * notice, this list of conditions and the following disclaimer. | |||
13 | * 2. Redistributions in binary form must reproduce the above copyright | |||
14 | * notice, this list of conditions and the following disclaimer in the | |||
15 | * documentation and/or other materials provided with the distribution. | |||
16 | * 3. Neither the name of the University nor the names of its contributors | |||
17 | * may be used to endorse or promote products derived from this software | |||
18 | * without specific prior written permission. | |||
19 | * | |||
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
30 | * SUCH DAMAGE. | |||
31 | */ | |||
32 | ||||
33 | #include <sys/types.h> | |||
34 | #include <sys/ioctl.h> | |||
35 | #include <sys/protosw.h> | |||
36 | #include <sys/socket.h> | |||
37 | #include <sys/sysctl.h> | |||
38 | ||||
39 | #include <net/if.h> | |||
40 | #include <net/if_dl.h> | |||
41 | #include <net/if_types.h> | |||
42 | #include <net/route.h> | |||
43 | #include <netinet/in.h> | |||
44 | #include <netinet/in_var.h> | |||
45 | #include <netinet/if_ether.h> | |||
46 | #include <arpa/inet.h> | |||
47 | ||||
48 | #include <err.h> | |||
49 | #include <limits.h> | |||
50 | #include <signal.h> | |||
51 | #include <stdio.h> | |||
52 | #include <stdlib.h> | |||
53 | #include <string.h> | |||
54 | #include <unistd.h> | |||
55 | #include <util.h> | |||
56 | ||||
57 | #define roundup(x, y)((((x)+((y)-1))/(y))*(y)) ((((x)+((y)-1))/(y))*(y)) | |||
58 | ||||
59 | #include "netstat.h" | |||
60 | ||||
61 | static void print_addr(struct sockaddr *, struct sockaddr **, struct if_data *); | |||
62 | static void sidewaysintpr(u_int, int); | |||
63 | static void catchalarm(int); | |||
64 | static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); | |||
65 | static void fetchifs(void); | |||
66 | ||||
67 | struct iftot; | |||
68 | ||||
69 | struct if_show_err { | |||
70 | const char *name; | |||
71 | const char *iname; | |||
72 | const char *oname; | |||
73 | uint64_t (*count)(uint64_t, uint64_t); | |||
74 | }; | |||
75 | ||||
76 | static uint64_t if_show_fails(uint64_t, uint64_t); | |||
77 | static uint64_t if_show_errors(uint64_t, uint64_t); | |||
78 | static uint64_t if_show_qdrops(uint64_t, uint64_t); | |||
79 | ||||
80 | static const struct if_show_err if_show_errs[] = { | |||
81 | [IF_SHOW_FAIL0] = { "fails", "Ifail", "Ofail", if_show_fails }, | |||
82 | [IF_SHOW_ERRS1] = { "errs", "Ierrs", "Oerrs", if_show_errors }, | |||
83 | [IF_SHOW_DROP2] = { "drops", "Idrop", "Odrop", if_show_qdrops }, | |||
84 | }; | |||
85 | static const struct if_show_err *if_errs = if_show_errs; | |||
86 | ||||
87 | /* | |||
88 | * Print a description of the network interfaces. | |||
89 | * NOTE: ifnetaddr is the location of the kernel global "ifnet", | |||
90 | * which is a TAILQ_HEAD. | |||
91 | */ | |||
92 | void | |||
93 | intpr(int interval, int repeatcount) | |||
94 | { | |||
95 | struct if_msghdr ifm; | |||
96 | int mib[6] = { CTL_NET4, PF_ROUTE17, 0, 0, NET_RT_IFLIST3, 0 }; | |||
97 | char name[IFNAMSIZ16 + 1]; /* + 1 for the '*' */ | |||
98 | char *buf = NULL((void *)0), *next, *lim, *cp; | |||
99 | struct rt_msghdr *rtm; | |||
100 | struct ifa_msghdr *ifam; | |||
101 | struct if_data *ifd; | |||
| ||||
102 | struct sockaddr *sa, *rti_info[RTAX_MAX15]; | |||
103 | struct sockaddr_dl *sdl; | |||
104 | u_int64_t total = 0; | |||
105 | size_t len; | |||
106 | ||||
107 | if_errs = &if_show_errs[dflag]; | |||
108 | ||||
109 | if (interval) { | |||
110 | sidewaysintpr((unsigned)interval, repeatcount); | |||
111 | return; | |||
112 | } | |||
113 | ||||
114 | len = get_sysctl(mib, 6, &buf); | |||
115 | ||||
116 | printf("%-7.7s %-5.5s %-11.11s %-17.17s ", | |||
117 | "Name", "Mtu", "Network", "Address"); | |||
118 | if (bflag) | |||
119 | printf("%10.10s %10.10s", "Ibytes", "Obytes"); | |||
120 | else { | |||
121 | printf("%8.8s %5.5s %8.8s %5.5s %5.5s", | |||
122 | "Ipkts", if_errs->iname, | |||
123 | "Opkts", if_errs->oname, "Colls"); | |||
124 | } | |||
125 | if (tflag) | |||
126 | printf(" %s", "Time"); | |||
127 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
128 | ||||
129 | lim = buf + len; | |||
130 | for (next = buf; next < lim; next += rtm->rtm_msglen) { | |||
131 | rtm = (struct rt_msghdr *)next; | |||
132 | if (rtm->rtm_version != RTM_VERSION5) | |||
133 | continue; | |||
134 | switch (rtm->rtm_type) { | |||
135 | case RTM_IFINFO0xe: | |||
136 | total = 0; | |||
137 | bcopy(next, &ifm, sizeof ifm); | |||
138 | ifd = &ifm.ifm_data; | |||
139 | ||||
140 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
141 | get_rtaddrs(ifm.ifm_addrs, sa, rti_info); | |||
142 | ||||
143 | sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP4]; | |||
144 | if (sdl == NULL((void *)0) || sdl->sdl_family != AF_LINK18) | |||
145 | continue; | |||
146 | bzero(name, sizeof(name)); | |||
147 | if (sdl->sdl_nlen >= IFNAMSIZ16) | |||
148 | memcpy(name, sdl->sdl_data, IFNAMSIZ16 - 1); | |||
149 | else if (sdl->sdl_nlen > 0) | |||
150 | memcpy(name, sdl->sdl_data, sdl->sdl_nlen); | |||
151 | ||||
152 | if (interface != 0 && strcmp(name, interface) != 0) | |||
153 | continue; | |||
154 | ||||
155 | /* mark inactive interfaces with a '*' */ | |||
156 | cp = strchr(name, '\0'); | |||
157 | if ((ifm.ifm_flags & IFF_UP0x1) == 0) | |||
158 | *cp++ = '*'; | |||
159 | *cp = '\0'; | |||
160 | ||||
161 | if (qflag) { | |||
162 | total = ifd->ifi_ibytes + ifd->ifi_obytes + | |||
163 | ifd->ifi_ipackets + | |||
164 | ifd->ifi_opackets + | |||
165 | ifd->ifi_collisions; | |||
166 | total += if_errs->count(ifd->ifi_ierrors, | |||
167 | ifd->ifi_iqdrops); | |||
168 | total += if_errs->count(ifd->ifi_oerrors, | |||
169 | ifd->ifi_oqdrops); | |||
170 | if (tflag) | |||
171 | total += 0; // XXX ifnet.if_timer; | |||
172 | if (total == 0) | |||
173 | continue; | |||
174 | } | |||
175 | ||||
176 | printf("%-7s %-5d ", name, ifd->ifi_mtu); | |||
177 | print_addr(rti_info[RTAX_IFP4], rti_info, ifd); | |||
178 | break; | |||
179 | case RTM_NEWADDR0xc: | |||
180 | if (qflag && total == 0) | |||
181 | continue; | |||
182 | if (interface != 0 && strcmp(name, interface) != 0) | |||
183 | continue; | |||
184 | ||||
185 | ifam = (struct ifa_msghdr *)next; | |||
186 | if ((ifam->ifam_addrs & (RTA_NETMASK0x4 | RTA_IFA0x20 | | |||
187 | RTA_BRD0x80)) == 0) | |||
188 | break; | |||
189 | ||||
190 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
191 | get_rtaddrs(ifam->ifam_addrs, sa, rti_info); | |||
192 | ||||
193 | printf("%-7s %-5d ", name, ifd->ifi_mtu); | |||
| ||||
194 | print_addr(rti_info[RTAX_IFA5], rti_info, ifd); | |||
195 | break; | |||
196 | } | |||
197 | } | |||
198 | free(buf); | |||
199 | } | |||
200 | ||||
201 | static void | |||
202 | print_addr(struct sockaddr *sa, struct sockaddr **rtinfo, struct if_data *ifd) | |||
203 | { | |||
204 | struct sockaddr_dl *sdl; | |||
205 | struct sockaddr_in *sin; | |||
206 | struct sockaddr_in6 *sin6; | |||
207 | char *cp; | |||
208 | int m, n; | |||
209 | ||||
210 | switch (sa->sa_family) { | |||
211 | case AF_UNSPEC0: | |||
212 | printf("%-11.11s ", "none"); | |||
213 | printf("%-17.17s ", "none"); | |||
214 | break; | |||
215 | case AF_INET2: | |||
216 | sin = (struct sockaddr_in *)sa; | |||
217 | cp = netname4(sin->sin_addr.s_addr, | |||
218 | ((struct sockaddr_in *)rtinfo[RTAX_NETMASK2])->sin_addr.s_addr); | |||
219 | if (vflag) | |||
220 | n = strlen(cp) < 11 ? 11 : strlen(cp); | |||
221 | else | |||
222 | n = 11; | |||
223 | printf("%-*.*s ", n, n, cp); | |||
224 | cp = routename4(sin->sin_addr.s_addr); | |||
225 | if (vflag) | |||
226 | n = strlen(cp) < 17 ? 17 : strlen(cp); | |||
227 | else | |||
228 | n = 17; | |||
229 | printf("%-*.*s ", n, n, cp); | |||
230 | ||||
231 | break; | |||
232 | case AF_INET624: | |||
233 | sin6 = (struct sockaddr_in6 *)sa; | |||
234 | #ifdef __KAME__ | |||
235 | if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)(((&sin6->sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe ) && (((&sin6->sin6_addr)->__u6_addr.__u6_addr8 [1] & 0xc0) == 0x80)) && | |||
236 | sin6->sin6_scope_id == 0) { | |||
237 | sin6->sin6_scope_id = | |||
238 | ntohs(*(u_int16_t *)(__uint16_t)(__builtin_constant_p(*(u_int16_t *) &sin6-> sin6_addr.__u6_addr.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t )(*(u_int16_t *) &sin6->sin6_addr.__u6_addr.__u6_addr8 [2]) & 0xffU) << 8 | ((__uint16_t)(*(u_int16_t *) & sin6->sin6_addr.__u6_addr.__u6_addr8[2]) & 0xff00U) >> 8) : __swap16md(*(u_int16_t *) &sin6->sin6_addr.__u6_addr .__u6_addr8[2])) | |||
239 | &sin6->sin6_addr.s6_addr[2])(__uint16_t)(__builtin_constant_p(*(u_int16_t *) &sin6-> sin6_addr.__u6_addr.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t )(*(u_int16_t *) &sin6->sin6_addr.__u6_addr.__u6_addr8 [2]) & 0xffU) << 8 | ((__uint16_t)(*(u_int16_t *) & sin6->sin6_addr.__u6_addr.__u6_addr8[2]) & 0xff00U) >> 8) : __swap16md(*(u_int16_t *) &sin6->sin6_addr.__u6_addr .__u6_addr8[2])); | |||
240 | sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] = 0; | |||
241 | sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[3] = 0; | |||
242 | } | |||
243 | #endif | |||
244 | cp = netname6(sin6, | |||
245 | (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK2]); | |||
246 | if (vflag) | |||
247 | n = strlen(cp) < 11 ? 11 : strlen(cp); | |||
248 | else | |||
249 | n = 11; | |||
250 | printf("%-*.*s ", n, n, cp); | |||
251 | cp = routename6(sin6); | |||
252 | if (vflag) | |||
253 | n = strlen(cp) < 17 ? 17 : strlen(cp); | |||
254 | else | |||
255 | n = 17; | |||
256 | printf("%-*.*s ", n, n, cp); | |||
257 | break; | |||
258 | case AF_LINK18: | |||
259 | sdl = (struct sockaddr_dl *)sa; | |||
260 | m = printf("%-11.11s ", "<Link>"); | |||
261 | if (sdl->sdl_type == IFT_ETHER0x06 || | |||
262 | sdl->sdl_type == IFT_CARP0xf7 || | |||
263 | sdl->sdl_type == IFT_FDDI0x0f || | |||
264 | sdl->sdl_type == IFT_ISO880250x09) | |||
265 | printf("%-17.17s ", | |||
266 | ether_ntoa((struct ether_addr *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)))); | |||
267 | else { | |||
268 | cp = (char *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)); | |||
269 | n = sdl->sdl_alen; | |||
270 | goto hexprint; | |||
271 | } | |||
272 | break; | |||
273 | default: | |||
274 | m = printf("(%d)", sa->sa_family); | |||
275 | for (cp = sa->sa_len + (char *)sa; | |||
276 | --cp > sa->sa_data && (*cp == 0);) {} | |||
277 | n = cp - sa->sa_data + 1; | |||
278 | cp = sa->sa_data; | |||
279 | hexprint: | |||
280 | while (--n >= 0) | |||
281 | m += printf("%x%c", *cp++ & 0xff, | |||
282 | n > 0 ? '.' : ' '); | |||
283 | m = 30 - m; | |||
284 | while (m-- > 0) | |||
285 | putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', ( &__sF[1]))); | |||
286 | break; | |||
287 | } | |||
288 | if (bflag) { | |||
289 | if (hflag) { | |||
290 | char ibytes[FMT_SCALED_STRSIZE7]; | |||
291 | char obytes[FMT_SCALED_STRSIZE7]; | |||
292 | fmt_scaled(ifd->ifi_ibytes, ibytes); | |||
293 | fmt_scaled(ifd->ifi_obytes, obytes); | |||
294 | printf("%10s %10s", ibytes, obytes); | |||
295 | } else | |||
296 | printf("%10llu %10llu", | |||
297 | ifd->ifi_ibytes, ifd->ifi_obytes); | |||
298 | } else | |||
299 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
300 | ifd->ifi_ipackets, | |||
301 | if_errs->count(ifd->ifi_ierrors, ifd->ifi_iqdrops), | |||
302 | ifd->ifi_opackets, | |||
303 | if_errs->count(ifd->ifi_oerrors, ifd->ifi_oqdrops), | |||
304 | ifd->ifi_collisions); | |||
305 | if (tflag) | |||
306 | printf(" %4d", 0 /* XXX ifnet.if_timer */); | |||
307 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
308 | } | |||
309 | ||||
310 | struct iftot { | |||
311 | char ift_name[IFNAMSIZ16]; /* interface name */ | |||
312 | u_int64_t ift_ip; /* input packets */ | |||
313 | u_int64_t ift_ib; /* input bytes */ | |||
314 | u_int64_t ift_ie; /* input errors */ | |||
315 | u_int64_t ift_iq; /* input qdrops */ | |||
316 | u_int64_t ift_op; /* output packets */ | |||
317 | u_int64_t ift_ob; /* output bytes */ | |||
318 | u_int64_t ift_oe; /* output errors */ | |||
319 | u_int64_t ift_oq; /* output qdrops */ | |||
320 | u_int64_t ift_co; /* collisions */ | |||
321 | } ip_cur, ip_old, sum_cur, sum_old; | |||
322 | ||||
323 | volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ | |||
324 | ||||
325 | /* | |||
326 | * Print a running summary of interface statistics. | |||
327 | * Repeat display every interval seconds, showing statistics | |||
328 | * collected over that interval. Assumes that interval is non-zero. | |||
329 | * First line printed at top of screen is always cumulative. | |||
330 | */ | |||
331 | static void | |||
332 | sidewaysintpr(unsigned int interval, int repeatcount) | |||
333 | { | |||
334 | sigset_t emptyset; | |||
335 | int line; | |||
336 | char ibytes[FMT_SCALED_STRSIZE7]; | |||
337 | char obytes[FMT_SCALED_STRSIZE7]; | |||
338 | ||||
339 | fetchifs(); | |||
340 | if (ip_cur.ift_name[0] == '\0') { | |||
341 | fprintf(stderr(&__sF[2]), "%s: %s: unknown interface\n", | |||
342 | __progname, interface); | |||
343 | exit(1); | |||
344 | } | |||
345 | ||||
346 | (void)signal(SIGALRM14, catchalarm); | |||
347 | signalled = 0; | |||
348 | (void)alarm(interval); | |||
349 | banner: | |||
350 | if (bflag) | |||
351 | printf("%7.7s in %8.8s %6.6s out %5.5s", | |||
352 | ip_cur.ift_name, " ", | |||
353 | ip_cur.ift_name, " "); | |||
354 | else | |||
355 | printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", | |||
356 | ip_cur.ift_name, " ", | |||
357 | ip_cur.ift_name, " ", " "); | |||
358 | ||||
359 | if (bflag) | |||
360 | printf(" %7.7s in %8.8s %6.6s out %5.5s", | |||
361 | "total", " ", "total", " "); | |||
362 | else | |||
363 | printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", | |||
364 | "total", " ", "total", " ", " "); | |||
365 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
366 | if (bflag) | |||
367 | printf("%10.10s %8.8s %10.10s %5.5s", | |||
368 | "bytes", " ", "bytes", " "); | |||
369 | else | |||
370 | printf("%8.8s %5.5s %8.8s %5.5s %5.5s", | |||
371 | "packets", if_errs->name, | |||
372 | "packets", if_errs->name, "colls"); | |||
373 | ||||
374 | if (bflag) | |||
375 | printf("%10.10s %8.8s %10.10s %5.5s", | |||
376 | "bytes", " ", "bytes", " "); | |||
377 | else | |||
378 | printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", | |||
379 | "packets", "errs", "packets", "errs", "colls"); | |||
380 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
381 | fflush(stdout(&__sF[1])); | |||
382 | line = 0; | |||
383 | bzero(&ip_old, sizeof(ip_old)); | |||
384 | bzero(&sum_old, sizeof(sum_old)); | |||
385 | loop: | |||
386 | bzero(&sum_cur, sizeof(sum_cur)); | |||
387 | ||||
388 | fetchifs(); | |||
389 | ||||
390 | if (bflag) { | |||
391 | if (hflag) { | |||
392 | fmt_scaled(ip_cur.ift_ib - ip_old.ift_ib, ibytes); | |||
393 | fmt_scaled(ip_cur.ift_ob - ip_old.ift_ob, obytes); | |||
394 | printf("%10s %8.8s %10s %5.5s", | |||
395 | ibytes, " ", obytes, " "); | |||
396 | } else | |||
397 | printf("%10llu %8.8s %10llu %5.5s", | |||
398 | ip_cur.ift_ib - ip_old.ift_ib, " ", | |||
399 | ip_cur.ift_ob - ip_old.ift_ob, " "); | |||
400 | } else | |||
401 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
402 | ip_cur.ift_ip - ip_old.ift_ip, | |||
403 | if_errs->count(ip_cur.ift_ie - ip_old.ift_ie, | |||
404 | ip_cur.ift_iq - ip_old.ift_iq), | |||
405 | ip_cur.ift_op - ip_old.ift_op, | |||
406 | if_errs->count(ip_cur.ift_oe - ip_old.ift_oe, | |||
407 | ip_cur.ift_oq - ip_old.ift_oq), | |||
408 | ip_cur.ift_co - ip_old.ift_co); | |||
409 | ||||
410 | ip_old = ip_cur; | |||
411 | ||||
412 | if (bflag) { | |||
413 | if (hflag) { | |||
414 | fmt_scaled(sum_cur.ift_ib - sum_old.ift_ib, ibytes); | |||
415 | fmt_scaled(sum_cur.ift_ob - sum_old.ift_ob, obytes); | |||
416 | printf("%10s %8.8s %10s %5.5s", | |||
417 | ibytes, " ", obytes, " "); | |||
418 | } else | |||
419 | printf("%10llu %8.8s %10llu %5.5s", | |||
420 | sum_cur.ift_ib - sum_old.ift_ib, " ", | |||
421 | sum_cur.ift_ob - sum_old.ift_ob, " "); | |||
422 | } else | |||
423 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
424 | sum_cur.ift_ip - sum_old.ift_ip, | |||
425 | if_errs->count(sum_cur.ift_ie - sum_old.ift_ie, | |||
426 | sum_cur.ift_iq - sum_old.ift_iq), | |||
427 | sum_cur.ift_op - sum_old.ift_op, | |||
428 | if_errs->count(sum_cur.ift_oe - sum_old.ift_oe, | |||
429 | sum_cur.ift_oq - sum_old.ift_oq), | |||
430 | sum_cur.ift_co - sum_old.ift_co); | |||
431 | ||||
432 | sum_old = sum_cur; | |||
433 | ||||
434 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
435 | fflush(stdout(&__sF[1])); | |||
436 | if (repeatcount && --repeatcount == 0) | |||
437 | return; | |||
438 | line++; | |||
439 | sigemptyset(&emptyset); | |||
440 | if (!signalled) | |||
441 | sigsuspend(&emptyset); | |||
442 | signalled = 0; | |||
443 | (void)alarm(interval); | |||
444 | if (line == 21 && isatty(STDOUT_FILENO1)) | |||
445 | goto banner; | |||
446 | goto loop; | |||
447 | } | |||
448 | ||||
449 | /* | |||
450 | * Called if an interval expires before sidewaysintpr has completed a loop. | |||
451 | * Sets a flag to not wait for the alarm. | |||
452 | */ | |||
453 | /* ARGSUSED */ | |||
454 | static void | |||
455 | catchalarm(int signo) | |||
456 | { | |||
457 | signalled = 1; | |||
458 | } | |||
459 | ||||
460 | static void | |||
461 | get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) | |||
462 | { | |||
463 | int i; | |||
464 | ||||
465 | for (i = 0; i < RTAX_MAX15; i++) { | |||
466 | if (addrs & (1 << i)) { | |||
467 | rti_info[i] = sa; | |||
468 | sa = (struct sockaddr *)((char *)(sa) + | |||
469 | roundup(sa->sa_len, sizeof(long))((((sa->sa_len)+((sizeof(long))-1))/(sizeof(long)))*(sizeof (long)))); | |||
470 | } else | |||
471 | rti_info[i] = NULL((void *)0); | |||
472 | } | |||
473 | } | |||
474 | ||||
475 | ||||
476 | static int | |||
477 | isegress(char *name) | |||
478 | { | |||
479 | static int s = -1; | |||
480 | int len; | |||
481 | struct ifgroupreq ifgr; | |||
482 | struct ifg_req *ifg; | |||
483 | int rv = 0; | |||
484 | ||||
485 | if (s == -1) { | |||
486 | if ((s = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1) | |||
487 | return 0; | |||
488 | } | |||
489 | ||||
490 | memset(&ifgr, 0, sizeof(ifgr)); | |||
491 | strlcpy(ifgr.ifgr_name, name, IFNAMSIZ16); | |||
492 | ||||
493 | if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifgroupreq) & 0x1fff) << 16) | ((('i')) << 8) | ((136))), (caddr_t)&ifgr) == -1) { | |||
494 | return 0; | |||
495 | } | |||
496 | ||||
497 | len = ifgr.ifgr_len; | |||
498 | ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(len, 1); | |||
499 | if (ifgr.ifgr_groupsifgr_ifgru.ifgru_groups == NULL((void *)0)) | |||
500 | err(1, "getifgroups"); | |||
501 | if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifgroupreq) & 0x1fff) << 16) | ((('i')) << 8) | ((136))), (caddr_t)&ifgr) == -1) | |||
502 | err(1, "SIOCGIFGROUP"); | |||
503 | ||||
504 | ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups; | |||
505 | for (; ifg && len >= sizeof(struct ifg_req); ifg++) { | |||
506 | len -= sizeof(struct ifg_req); | |||
507 | if (strcmp(ifg->ifgrq_groupifgrq_ifgrqu.ifgrqu_group, IFG_EGRESS"egress") == 0) | |||
508 | rv = 1; | |||
509 | } | |||
510 | ||||
511 | free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups); | |||
512 | return rv; | |||
513 | } | |||
514 | ||||
515 | static void | |||
516 | fetchifs(void) | |||
517 | { | |||
518 | struct if_msghdr ifm; | |||
519 | int mib[6] = { CTL_NET4, PF_ROUTE17, 0, 0, NET_RT_IFLIST3, 0 }; | |||
520 | struct rt_msghdr *rtm; | |||
521 | struct if_data *ifd; | |||
522 | struct sockaddr *sa, *rti_info[RTAX_MAX15]; | |||
523 | struct sockaddr_dl *sdl; | |||
524 | char *buf = NULL((void *)0), *next, *lim; | |||
525 | char name[IFNAMSIZ16]; | |||
526 | size_t len; | |||
527 | int takeit = 0; | |||
528 | int foundone = 0; | |||
529 | ||||
530 | len = get_sysctl(mib, 6, &buf); | |||
531 | ||||
532 | memset(&ip_cur, 0, sizeof(ip_cur)); | |||
533 | lim = buf + len; | |||
534 | for (next = buf; next < lim; next += rtm->rtm_msglen) { | |||
535 | rtm = (struct rt_msghdr *)next; | |||
536 | if (rtm->rtm_version != RTM_VERSION5) | |||
537 | continue; | |||
538 | switch (rtm->rtm_type) { | |||
539 | case RTM_IFINFO0xe: | |||
540 | bcopy(next, &ifm, sizeof ifm); | |||
541 | ifd = &ifm.ifm_data; | |||
542 | ||||
543 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
544 | get_rtaddrs(ifm.ifm_addrs, sa, rti_info); | |||
545 | ||||
546 | sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP4]; | |||
547 | if (sdl == NULL((void *)0) || sdl->sdl_family != AF_LINK18) | |||
548 | continue; | |||
549 | bzero(name, sizeof(name)); | |||
550 | if (sdl->sdl_nlen >= IFNAMSIZ16) | |||
551 | memcpy(name, sdl->sdl_data, IFNAMSIZ16 - 1); | |||
552 | else if (sdl->sdl_nlen > 0) | |||
553 | memcpy(name, sdl->sdl_data, sdl->sdl_nlen); | |||
554 | ||||
555 | if (interface != NULL((void *)0) && !strcmp(name, interface)) { | |||
556 | takeit = 1; | |||
557 | } else if (interface == NULL((void *)0) && foundone == 0 && | |||
558 | isegress(name)) { | |||
559 | takeit = 1; | |||
560 | foundone = 1; | |||
561 | } else | |||
562 | takeit = 0; | |||
563 | if (takeit) { | |||
564 | strlcpy(ip_cur.ift_name, name, | |||
565 | sizeof(ip_cur.ift_name)); | |||
566 | ip_cur.ift_ip = ifd->ifi_ipackets; | |||
567 | ip_cur.ift_ib = ifd->ifi_ibytes; | |||
568 | ip_cur.ift_ie = ifd->ifi_ierrors; | |||
569 | ip_cur.ift_iq = ifd->ifi_iqdrops; | |||
570 | ip_cur.ift_op = ifd->ifi_opackets; | |||
571 | ip_cur.ift_ob = ifd->ifi_obytes; | |||
572 | ip_cur.ift_oe = ifd->ifi_oerrors; | |||
573 | ip_cur.ift_oq = ifd->ifi_oqdrops; | |||
574 | ip_cur.ift_co = ifd->ifi_collisions; | |||
575 | } | |||
576 | ||||
577 | sum_cur.ift_ip += ifd->ifi_ipackets; | |||
578 | sum_cur.ift_ib += ifd->ifi_ibytes; | |||
579 | sum_cur.ift_ie += ifd->ifi_ierrors; | |||
580 | sum_cur.ift_iq += ifd->ifi_iqdrops; | |||
581 | sum_cur.ift_op += ifd->ifi_opackets; | |||
582 | sum_cur.ift_ob += ifd->ifi_obytes; | |||
583 | sum_cur.ift_oe += ifd->ifi_oerrors; | |||
584 | sum_cur.ift_oq += ifd->ifi_oqdrops; | |||
585 | sum_cur.ift_co += ifd->ifi_collisions; | |||
586 | break; | |||
587 | } | |||
588 | } | |||
589 | if (interface == NULL((void *)0) && foundone == 0) { | |||
590 | strlcpy(ip_cur.ift_name, name, | |||
591 | sizeof(ip_cur.ift_name)); | |||
592 | ip_cur.ift_ip = ifd->ifi_ipackets; | |||
593 | ip_cur.ift_ib = ifd->ifi_ibytes; | |||
594 | ip_cur.ift_ie = ifd->ifi_ierrors; | |||
595 | ip_cur.ift_iq = ifd->ifi_iqdrops; | |||
596 | ip_cur.ift_op = ifd->ifi_opackets; | |||
597 | ip_cur.ift_ob = ifd->ifi_obytes; | |||
598 | ip_cur.ift_oe = ifd->ifi_oerrors; | |||
599 | ip_cur.ift_oq = ifd->ifi_oqdrops; | |||
600 | ip_cur.ift_co = ifd->ifi_collisions; | |||
601 | } | |||
602 | free(buf); | |||
603 | } | |||
604 | ||||
605 | static uint64_t | |||
606 | if_show_fails(uint64_t errors, uint64_t qdrops) | |||
607 | { | |||
608 | return (errors + qdrops); | |||
609 | } | |||
610 | ||||
611 | static uint64_t | |||
612 | if_show_errors(uint64_t errors, uint64_t qdrops) | |||
613 | { | |||
614 | return (errors); | |||
615 | } | |||
616 | ||||
617 | static uint64_t | |||
618 | if_show_qdrops(uint64_t errors, uint64_t qdrops) | |||
619 | { | |||
620 | return (qdrops); | |||
621 | } |