File: | src/usr.bin/netstat/if.c |
Warning: | line 187, 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.81 2023/03/08 04:43:12 guenther 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 | */ | |||
90 | void | |||
91 | intpr(int interval, int repeatcount) | |||
92 | { | |||
93 | struct if_msghdr ifm; | |||
94 | int mib[6] = { CTL_NET4, PF_ROUTE17, 0, 0, NET_RT_IFLIST3, 0 }; | |||
95 | char name[IFNAMSIZ16 + 1]; /* + 1 for the '*' */ | |||
96 | char *buf = NULL((void *)0), *next, *lim, *cp; | |||
97 | struct rt_msghdr *rtm; | |||
98 | struct ifa_msghdr *ifam; | |||
99 | struct if_data *ifd; | |||
| ||||
100 | struct sockaddr *sa, *rti_info[RTAX_MAX15]; | |||
101 | struct sockaddr_dl *sdl; | |||
102 | u_int64_t total = 0; | |||
103 | size_t len; | |||
104 | ||||
105 | if_errs = &if_show_errs[dflag]; | |||
106 | ||||
107 | if (interval) { | |||
108 | sidewaysintpr((unsigned)interval, repeatcount); | |||
109 | return; | |||
110 | } | |||
111 | ||||
112 | len = get_sysctl(mib, 6, &buf); | |||
113 | ||||
114 | printf("%-7.7s %-5.5s %-11.11s %-17.17s ", | |||
115 | "Name", "Mtu", "Network", "Address"); | |||
116 | if (bflag) | |||
117 | printf("%10.10s %10.10s", "Ibytes", "Obytes"); | |||
118 | else { | |||
119 | printf("%8.8s %5.5s %8.8s %5.5s %5.5s", | |||
120 | "Ipkts", if_errs->iname, | |||
121 | "Opkts", if_errs->oname, "Colls"); | |||
122 | } | |||
123 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
124 | ||||
125 | lim = buf + len; | |||
126 | for (next = buf; next < lim; next += rtm->rtm_msglen) { | |||
127 | rtm = (struct rt_msghdr *)next; | |||
128 | if (rtm->rtm_version != RTM_VERSION5) | |||
129 | continue; | |||
130 | switch (rtm->rtm_type) { | |||
131 | case RTM_IFINFO0xe: | |||
132 | total = 0; | |||
133 | bcopy(next, &ifm, sizeof ifm); | |||
134 | ifd = &ifm.ifm_data; | |||
135 | ||||
136 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
137 | get_rtaddrs(ifm.ifm_addrs, sa, rti_info); | |||
138 | ||||
139 | sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP4]; | |||
140 | if (sdl == NULL((void *)0) || sdl->sdl_family != AF_LINK18) | |||
141 | continue; | |||
142 | bzero(name, sizeof(name)); | |||
143 | if (sdl->sdl_nlen >= IFNAMSIZ16) | |||
144 | memcpy(name, sdl->sdl_data, IFNAMSIZ16 - 1); | |||
145 | else if (sdl->sdl_nlen > 0) | |||
146 | memcpy(name, sdl->sdl_data, sdl->sdl_nlen); | |||
147 | ||||
148 | if (interface != 0 && strcmp(name, interface) != 0) | |||
149 | continue; | |||
150 | ||||
151 | /* mark inactive interfaces with a '*' */ | |||
152 | cp = strchr(name, '\0'); | |||
153 | if ((ifm.ifm_flags & IFF_UP0x1) == 0) | |||
154 | *cp++ = '*'; | |||
155 | *cp = '\0'; | |||
156 | ||||
157 | if (qflag) { | |||
158 | total = ifd->ifi_ibytes + ifd->ifi_obytes + | |||
159 | ifd->ifi_ipackets + | |||
160 | ifd->ifi_opackets + | |||
161 | ifd->ifi_collisions; | |||
162 | total += if_errs->count(ifd->ifi_ierrors, | |||
163 | ifd->ifi_iqdrops); | |||
164 | total += if_errs->count(ifd->ifi_oerrors, | |||
165 | ifd->ifi_oqdrops); | |||
166 | if (total == 0) | |||
167 | continue; | |||
168 | } | |||
169 | ||||
170 | printf("%-7s %-5d ", name, ifd->ifi_mtu); | |||
171 | print_addr(rti_info[RTAX_IFP4], rti_info, ifd); | |||
172 | break; | |||
173 | case RTM_NEWADDR0xc: | |||
174 | if (qflag && total == 0) | |||
175 | continue; | |||
176 | if (interface != 0 && strcmp(name, interface) != 0) | |||
177 | continue; | |||
178 | ||||
179 | ifam = (struct ifa_msghdr *)next; | |||
180 | if ((ifam->ifam_addrs & (RTA_NETMASK0x4 | RTA_IFA0x20 | | |||
181 | RTA_BRD0x80)) == 0) | |||
182 | break; | |||
183 | ||||
184 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
185 | get_rtaddrs(ifam->ifam_addrs, sa, rti_info); | |||
186 | ||||
187 | printf("%-7s %-5d ", name, ifd->ifi_mtu); | |||
| ||||
188 | print_addr(rti_info[RTAX_IFA5], rti_info, ifd); | |||
189 | break; | |||
190 | } | |||
191 | } | |||
192 | free(buf); | |||
193 | } | |||
194 | ||||
195 | static void | |||
196 | print_addr(struct sockaddr *sa, struct sockaddr **rtinfo, struct if_data *ifd) | |||
197 | { | |||
198 | struct sockaddr_dl *sdl; | |||
199 | struct sockaddr_in *sin; | |||
200 | struct sockaddr_in6 *sin6; | |||
201 | char *cp; | |||
202 | int m, n; | |||
203 | ||||
204 | switch (sa->sa_family) { | |||
205 | case AF_UNSPEC0: | |||
206 | printf("%-11.11s ", "none"); | |||
207 | printf("%-17.17s ", "none"); | |||
208 | break; | |||
209 | case AF_INET2: | |||
210 | sin = (struct sockaddr_in *)sa; | |||
211 | cp = netname4(sin->sin_addr.s_addr, | |||
212 | ((struct sockaddr_in *)rtinfo[RTAX_NETMASK2])->sin_addr.s_addr); | |||
213 | if (vflag) | |||
214 | n = strlen(cp) < 11 ? 11 : strlen(cp); | |||
215 | else | |||
216 | n = 11; | |||
217 | printf("%-*.*s ", n, n, cp); | |||
218 | cp = routename4(sin->sin_addr.s_addr); | |||
219 | if (vflag) | |||
220 | n = strlen(cp) < 17 ? 17 : strlen(cp); | |||
221 | else | |||
222 | n = 17; | |||
223 | printf("%-*.*s ", n, n, cp); | |||
224 | ||||
225 | break; | |||
226 | case AF_INET624: | |||
227 | sin6 = (struct sockaddr_in6 *)sa; | |||
228 | #ifdef __KAME__ | |||
229 | 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)) && | |||
230 | sin6->sin6_scope_id == 0) { | |||
231 | sin6->sin6_scope_id = | |||
232 | 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])) | |||
233 | &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])); | |||
234 | sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] = 0; | |||
235 | sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[3] = 0; | |||
236 | } | |||
237 | #endif | |||
238 | cp = netname6(sin6, | |||
239 | (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK2]); | |||
240 | if (vflag) | |||
241 | n = strlen(cp) < 11 ? 11 : strlen(cp); | |||
242 | else | |||
243 | n = 11; | |||
244 | printf("%-*.*s ", n, n, cp); | |||
245 | cp = routename6(sin6); | |||
246 | if (vflag) | |||
247 | n = strlen(cp) < 17 ? 17 : strlen(cp); | |||
248 | else | |||
249 | n = 17; | |||
250 | printf("%-*.*s ", n, n, cp); | |||
251 | break; | |||
252 | case AF_LINK18: | |||
253 | sdl = (struct sockaddr_dl *)sa; | |||
254 | m = printf("%-11.11s ", "<Link>"); | |||
255 | if (sdl->sdl_type == IFT_ETHER0x06 || | |||
256 | sdl->sdl_type == IFT_CARP0xf7 || | |||
257 | sdl->sdl_type == IFT_FDDI0x0f || | |||
258 | sdl->sdl_type == IFT_ISO880250x09) | |||
259 | printf("%-17.17s ", | |||
260 | ether_ntoa((struct ether_addr *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)))); | |||
261 | else { | |||
262 | cp = (char *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)); | |||
263 | n = sdl->sdl_alen; | |||
264 | goto hexprint; | |||
265 | } | |||
266 | break; | |||
267 | default: | |||
268 | m = printf("(%d)", sa->sa_family); | |||
269 | for (cp = sa->sa_len + (char *)sa; | |||
270 | --cp > sa->sa_data && (*cp == 0);) {} | |||
271 | n = cp - sa->sa_data + 1; | |||
272 | cp = sa->sa_data; | |||
273 | hexprint: | |||
274 | while (--n >= 0) | |||
275 | m += printf("%x%c", *cp++ & 0xff, | |||
276 | n > 0 ? '.' : ' '); | |||
277 | m = 30 - m; | |||
278 | while (m-- > 0) | |||
279 | putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', ( &__sF[1]))); | |||
280 | break; | |||
281 | } | |||
282 | if (bflag) { | |||
283 | if (hflag) { | |||
284 | char ibytes[FMT_SCALED_STRSIZE7]; | |||
285 | char obytes[FMT_SCALED_STRSIZE7]; | |||
286 | fmt_scaled(ifd->ifi_ibytes, ibytes); | |||
287 | fmt_scaled(ifd->ifi_obytes, obytes); | |||
288 | printf("%10s %10s", ibytes, obytes); | |||
289 | } else | |||
290 | printf("%10llu %10llu", | |||
291 | ifd->ifi_ibytes, ifd->ifi_obytes); | |||
292 | } else | |||
293 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
294 | ifd->ifi_ipackets, | |||
295 | if_errs->count(ifd->ifi_ierrors, ifd->ifi_iqdrops), | |||
296 | ifd->ifi_opackets, | |||
297 | if_errs->count(ifd->ifi_oerrors, ifd->ifi_oqdrops), | |||
298 | ifd->ifi_collisions); | |||
299 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
300 | } | |||
301 | ||||
302 | struct iftot { | |||
303 | char ift_name[IFNAMSIZ16]; /* interface name */ | |||
304 | u_int64_t ift_ip; /* input packets */ | |||
305 | u_int64_t ift_ib; /* input bytes */ | |||
306 | u_int64_t ift_ie; /* input errors */ | |||
307 | u_int64_t ift_iq; /* input qdrops */ | |||
308 | u_int64_t ift_op; /* output packets */ | |||
309 | u_int64_t ift_ob; /* output bytes */ | |||
310 | u_int64_t ift_oe; /* output errors */ | |||
311 | u_int64_t ift_oq; /* output qdrops */ | |||
312 | u_int64_t ift_co; /* collisions */ | |||
313 | } ip_cur, ip_old, sum_cur, sum_old; | |||
314 | ||||
315 | volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ | |||
316 | ||||
317 | /* | |||
318 | * Print a running summary of interface statistics. | |||
319 | * Repeat display every interval seconds, showing statistics | |||
320 | * collected over that interval. Assumes that interval is non-zero. | |||
321 | * First line printed at top of screen is always cumulative. | |||
322 | */ | |||
323 | static void | |||
324 | sidewaysintpr(unsigned int interval, int repeatcount) | |||
325 | { | |||
326 | sigset_t emptyset; | |||
327 | int line; | |||
328 | char ibytes[FMT_SCALED_STRSIZE7]; | |||
329 | char obytes[FMT_SCALED_STRSIZE7]; | |||
330 | ||||
331 | fetchifs(); | |||
332 | if (ip_cur.ift_name[0] == '\0') { | |||
333 | fprintf(stderr(&__sF[2]), "%s: %s: unknown interface\n", | |||
334 | __progname, interface); | |||
335 | exit(1); | |||
336 | } | |||
337 | ||||
338 | (void)signal(SIGALRM14, catchalarm); | |||
339 | signalled = 0; | |||
340 | (void)alarm(interval); | |||
341 | banner: | |||
342 | if (bflag) | |||
343 | printf("%7.7s in %8.8s %6.6s out %5.5s", | |||
344 | ip_cur.ift_name, " ", | |||
345 | ip_cur.ift_name, " "); | |||
346 | else | |||
347 | printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", | |||
348 | ip_cur.ift_name, " ", | |||
349 | ip_cur.ift_name, " ", " "); | |||
350 | ||||
351 | if (bflag) | |||
352 | printf(" %7.7s in %8.8s %6.6s out %5.5s", | |||
353 | "total", " ", "total", " "); | |||
354 | else | |||
355 | printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", | |||
356 | "total", " ", "total", " ", " "); | |||
357 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
358 | if (bflag) | |||
359 | printf("%10.10s %8.8s %10.10s %5.5s", | |||
360 | "bytes", " ", "bytes", " "); | |||
361 | else | |||
362 | printf("%8.8s %5.5s %8.8s %5.5s %5.5s", | |||
363 | "packets", if_errs->name, | |||
364 | "packets", if_errs->name, "colls"); | |||
365 | ||||
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", "errs", "packets", "errs", "colls"); | |||
372 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
373 | fflush(stdout(&__sF[1])); | |||
374 | line = 0; | |||
375 | bzero(&ip_old, sizeof(ip_old)); | |||
376 | bzero(&sum_old, sizeof(sum_old)); | |||
377 | loop: | |||
378 | bzero(&sum_cur, sizeof(sum_cur)); | |||
379 | ||||
380 | fetchifs(); | |||
381 | ||||
382 | if (bflag) { | |||
383 | if (hflag) { | |||
384 | fmt_scaled(ip_cur.ift_ib - ip_old.ift_ib, ibytes); | |||
385 | fmt_scaled(ip_cur.ift_ob - ip_old.ift_ob, obytes); | |||
386 | printf("%10s %8.8s %10s %5.5s", | |||
387 | ibytes, " ", obytes, " "); | |||
388 | } else | |||
389 | printf("%10llu %8.8s %10llu %5.5s", | |||
390 | ip_cur.ift_ib - ip_old.ift_ib, " ", | |||
391 | ip_cur.ift_ob - ip_old.ift_ob, " "); | |||
392 | } else | |||
393 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
394 | ip_cur.ift_ip - ip_old.ift_ip, | |||
395 | if_errs->count(ip_cur.ift_ie - ip_old.ift_ie, | |||
396 | ip_cur.ift_iq - ip_old.ift_iq), | |||
397 | ip_cur.ift_op - ip_old.ift_op, | |||
398 | if_errs->count(ip_cur.ift_oe - ip_old.ift_oe, | |||
399 | ip_cur.ift_oq - ip_old.ift_oq), | |||
400 | ip_cur.ift_co - ip_old.ift_co); | |||
401 | ||||
402 | ip_old = ip_cur; | |||
403 | ||||
404 | if (bflag) { | |||
405 | if (hflag) { | |||
406 | fmt_scaled(sum_cur.ift_ib - sum_old.ift_ib, ibytes); | |||
407 | fmt_scaled(sum_cur.ift_ob - sum_old.ift_ob, obytes); | |||
408 | printf("%10s %8.8s %10s %5.5s", | |||
409 | ibytes, " ", obytes, " "); | |||
410 | } else | |||
411 | printf("%10llu %8.8s %10llu %5.5s", | |||
412 | sum_cur.ift_ib - sum_old.ift_ib, " ", | |||
413 | sum_cur.ift_ob - sum_old.ift_ob, " "); | |||
414 | } else | |||
415 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
416 | sum_cur.ift_ip - sum_old.ift_ip, | |||
417 | if_errs->count(sum_cur.ift_ie - sum_old.ift_ie, | |||
418 | sum_cur.ift_iq - sum_old.ift_iq), | |||
419 | sum_cur.ift_op - sum_old.ift_op, | |||
420 | if_errs->count(sum_cur.ift_oe - sum_old.ift_oe, | |||
421 | sum_cur.ift_oq - sum_old.ift_oq), | |||
422 | sum_cur.ift_co - sum_old.ift_co); | |||
423 | ||||
424 | sum_old = sum_cur; | |||
425 | ||||
426 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
427 | fflush(stdout(&__sF[1])); | |||
428 | if (repeatcount && --repeatcount == 0) | |||
429 | return; | |||
430 | line++; | |||
431 | sigemptyset(&emptyset); | |||
432 | if (!signalled) | |||
433 | sigsuspend(&emptyset); | |||
434 | signalled = 0; | |||
435 | (void)alarm(interval); | |||
436 | if (line == 21 && isatty(STDOUT_FILENO1)) | |||
437 | goto banner; | |||
438 | goto loop; | |||
439 | } | |||
440 | ||||
441 | /* | |||
442 | * Called if an interval expires before sidewaysintpr has completed a loop. | |||
443 | * Sets a flag to not wait for the alarm. | |||
444 | */ | |||
445 | static void | |||
446 | catchalarm(int signo) | |||
447 | { | |||
448 | signalled = 1; | |||
449 | } | |||
450 | ||||
451 | static void | |||
452 | get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) | |||
453 | { | |||
454 | int i; | |||
455 | ||||
456 | for (i = 0; i < RTAX_MAX15; i++) { | |||
457 | if (addrs & (1 << i)) { | |||
458 | rti_info[i] = sa; | |||
459 | sa = (struct sockaddr *)((char *)(sa) + | |||
460 | roundup(sa->sa_len, sizeof(long))((((sa->sa_len)+((sizeof(long))-1))/(sizeof(long)))*(sizeof (long)))); | |||
461 | } else | |||
462 | rti_info[i] = NULL((void *)0); | |||
463 | } | |||
464 | } | |||
465 | ||||
466 | ||||
467 | static int | |||
468 | isegress(char *name) | |||
469 | { | |||
470 | static int s = -1; | |||
471 | int len; | |||
472 | struct ifgroupreq ifgr; | |||
473 | struct ifg_req *ifg; | |||
474 | int rv = 0; | |||
475 | ||||
476 | if (s == -1) { | |||
477 | if ((s = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1) | |||
478 | return 0; | |||
479 | } | |||
480 | ||||
481 | memset(&ifgr, 0, sizeof(ifgr)); | |||
482 | strlcpy(ifgr.ifgr_name, name, IFNAMSIZ16); | |||
483 | ||||
484 | if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifgroupreq) & 0x1fff) << 16) | ((('i')) << 8) | ((136))), (caddr_t)&ifgr) == -1) { | |||
485 | return 0; | |||
486 | } | |||
487 | ||||
488 | len = ifgr.ifgr_len; | |||
489 | ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(len, 1); | |||
490 | if (ifgr.ifgr_groupsifgr_ifgru.ifgru_groups == NULL((void *)0)) | |||
491 | err(1, "getifgroups"); | |||
492 | if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifgroupreq) & 0x1fff) << 16) | ((('i')) << 8) | ((136))), (caddr_t)&ifgr) == -1) | |||
493 | err(1, "SIOCGIFGROUP"); | |||
494 | ||||
495 | ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups; | |||
496 | for (; ifg && len >= sizeof(struct ifg_req); ifg++) { | |||
497 | len -= sizeof(struct ifg_req); | |||
498 | if (strcmp(ifg->ifgrq_groupifgrq_ifgrqu.ifgrqu_group, IFG_EGRESS"egress") == 0) | |||
499 | rv = 1; | |||
500 | } | |||
501 | ||||
502 | free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups); | |||
503 | return rv; | |||
504 | } | |||
505 | ||||
506 | static void | |||
507 | fetchifs(void) | |||
508 | { | |||
509 | struct if_msghdr ifm; | |||
510 | int mib[6] = { CTL_NET4, PF_ROUTE17, 0, 0, NET_RT_IFLIST3, 0 }; | |||
511 | struct rt_msghdr *rtm; | |||
512 | struct if_data *ifd; | |||
513 | struct sockaddr *sa, *rti_info[RTAX_MAX15]; | |||
514 | struct sockaddr_dl *sdl; | |||
515 | char *buf = NULL((void *)0), *next, *lim; | |||
516 | char name[IFNAMSIZ16]; | |||
517 | size_t len; | |||
518 | int takeit = 0; | |||
519 | int foundone = 0; | |||
520 | ||||
521 | len = get_sysctl(mib, 6, &buf); | |||
522 | ||||
523 | memset(&ip_cur, 0, sizeof(ip_cur)); | |||
524 | lim = buf + len; | |||
525 | for (next = buf; next < lim; next += rtm->rtm_msglen) { | |||
526 | rtm = (struct rt_msghdr *)next; | |||
527 | if (rtm->rtm_version != RTM_VERSION5) | |||
528 | continue; | |||
529 | switch (rtm->rtm_type) { | |||
530 | case RTM_IFINFO0xe: | |||
531 | bcopy(next, &ifm, sizeof ifm); | |||
532 | ifd = &ifm.ifm_data; | |||
533 | ||||
534 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
535 | get_rtaddrs(ifm.ifm_addrs, sa, rti_info); | |||
536 | ||||
537 | sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP4]; | |||
538 | if (sdl == NULL((void *)0) || sdl->sdl_family != AF_LINK18) | |||
539 | continue; | |||
540 | bzero(name, sizeof(name)); | |||
541 | if (sdl->sdl_nlen >= IFNAMSIZ16) | |||
542 | memcpy(name, sdl->sdl_data, IFNAMSIZ16 - 1); | |||
543 | else if (sdl->sdl_nlen > 0) | |||
544 | memcpy(name, sdl->sdl_data, sdl->sdl_nlen); | |||
545 | ||||
546 | if (interface != NULL((void *)0) && !strcmp(name, interface)) { | |||
547 | takeit = 1; | |||
548 | } else if (interface == NULL((void *)0) && foundone == 0 && | |||
549 | isegress(name)) { | |||
550 | takeit = 1; | |||
551 | foundone = 1; | |||
552 | } else | |||
553 | takeit = 0; | |||
554 | if (takeit) { | |||
555 | strlcpy(ip_cur.ift_name, name, | |||
556 | sizeof(ip_cur.ift_name)); | |||
557 | ip_cur.ift_ip = ifd->ifi_ipackets; | |||
558 | ip_cur.ift_ib = ifd->ifi_ibytes; | |||
559 | ip_cur.ift_ie = ifd->ifi_ierrors; | |||
560 | ip_cur.ift_iq = ifd->ifi_iqdrops; | |||
561 | ip_cur.ift_op = ifd->ifi_opackets; | |||
562 | ip_cur.ift_ob = ifd->ifi_obytes; | |||
563 | ip_cur.ift_oe = ifd->ifi_oerrors; | |||
564 | ip_cur.ift_oq = ifd->ifi_oqdrops; | |||
565 | ip_cur.ift_co = ifd->ifi_collisions; | |||
566 | } | |||
567 | ||||
568 | sum_cur.ift_ip += ifd->ifi_ipackets; | |||
569 | sum_cur.ift_ib += ifd->ifi_ibytes; | |||
570 | sum_cur.ift_ie += ifd->ifi_ierrors; | |||
571 | sum_cur.ift_iq += ifd->ifi_iqdrops; | |||
572 | sum_cur.ift_op += ifd->ifi_opackets; | |||
573 | sum_cur.ift_ob += ifd->ifi_obytes; | |||
574 | sum_cur.ift_oe += ifd->ifi_oerrors; | |||
575 | sum_cur.ift_oq += ifd->ifi_oqdrops; | |||
576 | sum_cur.ift_co += ifd->ifi_collisions; | |||
577 | break; | |||
578 | } | |||
579 | } | |||
580 | if (interface == NULL((void *)0) && foundone == 0) { | |||
581 | strlcpy(ip_cur.ift_name, name, | |||
582 | sizeof(ip_cur.ift_name)); | |||
583 | ip_cur.ift_ip = ifd->ifi_ipackets; | |||
584 | ip_cur.ift_ib = ifd->ifi_ibytes; | |||
585 | ip_cur.ift_ie = ifd->ifi_ierrors; | |||
586 | ip_cur.ift_iq = ifd->ifi_iqdrops; | |||
587 | ip_cur.ift_op = ifd->ifi_opackets; | |||
588 | ip_cur.ift_ob = ifd->ifi_obytes; | |||
589 | ip_cur.ift_oe = ifd->ifi_oerrors; | |||
590 | ip_cur.ift_oq = ifd->ifi_oqdrops; | |||
591 | ip_cur.ift_co = ifd->ifi_collisions; | |||
592 | } | |||
593 | free(buf); | |||
594 | } | |||
595 | ||||
596 | static uint64_t | |||
597 | if_show_fails(uint64_t errors, uint64_t qdrops) | |||
598 | { | |||
599 | return (errors + qdrops); | |||
600 | } | |||
601 | ||||
602 | static uint64_t | |||
603 | if_show_errors(uint64_t errors, uint64_t qdrops) | |||
604 | { | |||
605 | return (errors); | |||
606 | } | |||
607 | ||||
608 | static uint64_t | |||
609 | if_show_qdrops(uint64_t errors, uint64_t qdrops) | |||
610 | { | |||
611 | return (qdrops); | |||
612 | } |