Bug Summary

File:src/usr.sbin/dvmrpctl/dvmrpctl.c
Warning:line 522, column 3
Value stored to 'nbr' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name dvmrpctl.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/dvmrpctl/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/dvmrpctl -I /usr/src/usr.sbin/dvmrpctl/../dvmrpd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/dvmrpctl/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/dvmrpctl/dvmrpctl.c
1/* $OpenBSD: dvmrpctl.c,v 1.15 2015/12/05 13:11:00 claudio Exp $ */
2
3/*
4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5 * Copyright (c) 2004, 2005, 2006 Esben Norby <norby@openbsd.org>
6 * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <sys/un.h>
24#include <netinet/in.h>
25#include <netinet/ip_mroute.h>
26#include <arpa/inet.h>
27#include <net/if_types.h>
28
29#include <err.h>
30#include <errno(*__errno()).h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35
36#include "igmp.h"
37#include "dvmrp.h"
38#include "dvmrpd.h"
39#include "dvmrpe.h"
40#include "parser.h"
41#include "log.h"
42
43__dead__attribute__((__noreturn__)) void usage(void);
44int show_summary_msg(struct imsg *);
45int show_interface_msg(struct imsg *);
46int show_interface_detail_msg(struct imsg *);
47int show_igmp_msg(struct imsg *);
48const char *print_if_type(enum iface_type type);
49const char *print_nbr_state(int);
50const char *print_link(int);
51const char *fmt_timeframe(time_t t);
52const char *fmt_timeframe_core(time_t t);
53int show_nbr_msg(struct imsg *);
54const char *print_dvmrp_options(u_int8_t);
55int show_nbr_detail_msg(struct imsg *);
56int show_rib_msg(struct imsg *);
57int show_rib_detail_msg(struct imsg *);
58int show_mfc_msg(struct imsg *);
59int show_mfc_detail_msg(struct imsg *);
60const char * get_linkstate(uint8_t, int);
61
62struct imsgbuf *ibuf;
63
64__dead__attribute__((__noreturn__)) void
65usage(void)
66{
67 extern char *__progname;
68
69 fprintf(stderr(&__sF[2]), "usage: %s command [argument ...]\n", __progname);
70 exit(1);
71}
72
73int
74main(int argc, char *argv[])
75{
76 struct sockaddr_un sun;
77 struct parse_result *res;
78 struct imsg imsg;
79 unsigned int ifidx = 0;
80 int ctl_sock;
81 int done = 0, verbose = 0;
82 int n;
83
84 /* parse options */
85 if ((res = parse(argc - 1, argv + 1)) == NULL((void *)0))
86 exit(1);
87
88 /* connect to dvmrpd control socket */
89 if ((ctl_sock = socket(AF_UNIX1, SOCK_STREAM1, 0)) == -1)
90 err(1, "socket");
91
92 bzero(&sun, sizeof(sun));
93 sun.sun_family = AF_UNIX1;
94 strlcpy(sun.sun_path, DVMRPD_SOCKET"/var/run/dvmrpd.sock", sizeof(sun.sun_path));
95 if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
96 err(1, "connect: %s", DVMRPD_SOCKET"/var/run/dvmrpd.sock");
97
98 if (pledge("stdio", NULL((void *)0)) == -1)
99 err(1, "pledge");
100
101 if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL((void *)0))
102 fatal(NULL((void *)0));
103 imsg_init(ibuf, ctl_sock);
104 done = 0;
105
106 /* process user request */
107 switch (res->action) {
108 case NONE:
109 usage();
110 /* NOTREACHED */
111 case SHOW:
112 case SHOW_SUM:
113 imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL((void *)0), 0);
114 break;
115 case SHOW_IFACE:
116 printf("%-11s %-18s %-10s %-10s %-10s %-8s %s\n",
117 "Interface", "Address", "State", "ProbeTimer", "Linkstate",
118 "Uptime", "Groups");
119 /* FALLTHROUGH */
120 case SHOW_IFACE_DTAIL:
121 if (*res->ifname) {
122 ifidx = if_nametoindex(res->ifname);
123 if (ifidx == 0)
124 errx(1, "no such interface %s", res->ifname);
125 }
126 imsg_compose(ibuf, IMSG_CTL_SHOW_IFACE, 0, 0, -1, &ifidx,
127 sizeof(ifidx));
128 break;
129 case SHOW_IGMP:
130 if (*res->ifname) {
131 ifidx = if_nametoindex(res->ifname);
132 if (ifidx == 0)
133 errx(1, "no such interface %s", res->ifname);
134 }
135 imsg_compose(ibuf, IMSG_CTL_SHOW_IGMP, 0, 0, -1, &ifidx,
136 sizeof(ifidx));
137 break;
138 case SHOW_NBR:
139 printf("%-15s %-10s %-9s %-15s %-11s %-8s\n", "ID", "State",
140 "DeadTime", "Address", "Interface", "Uptime");
141 /* FALLTHROUGH */
142 case SHOW_NBR_DTAIL:
143 imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL((void *)0), 0);
144 break;
145 case SHOW_RIB:
146 printf("%-20s %-17s %-7s %-10s %-s\n", "Destination", "Nexthop",
147 "Cost", "Uptime", "Expire");
148 /* FALLTHROUGH */
149 case SHOW_RIB_DTAIL:
150 imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL((void *)0), 0);
151 break;
152 case SHOW_MFC:
153 printf("%-16s %-16s %-9s %-9s %-4s %-10s %-10s\n", "Group",
154 "Origin", "Incoming", "Outgoing", "TTL", "Uptime",
155 "Expire");
156 /* FALLTHROUGH */
157 case SHOW_MFC_DTAIL:
158 imsg_compose(ibuf, IMSG_CTL_SHOW_MFC, 0, 0, -1, NULL((void *)0), 0);
159 break;
160 case LOG_VERBOSE:
161 verbose = 1;
162 /* FALLTHROUGH */
163 case LOG_BRIEF:
164 imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1,
165 &verbose, sizeof(verbose));
166 printf("logging request sent.\n");
167 done = 1;
168 break;
169 case RELOAD:
170 imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL((void *)0), 0);
171 printf("reload request sent.\n");
172 done = 1;
173 break;
174 }
175
176 while (ibuf->w.queued)
177 if (msgbuf_write(&ibuf->w) <= 0 && errno(*__errno()) != EAGAIN35)
178 err(1, "write error");
179
180 while (!done) {
181 if ((n = imsg_read(ibuf)) == -1 && errno(*__errno()) != EAGAIN35)
182 errx(1, "imsg_read error");
183 if (n == 0)
184 errx(1, "pipe closed");
185
186 while (!done) {
187 if ((n = imsg_get(ibuf, &imsg)) == -1)
188 errx(1, "imsg_get error");
189 if (n == 0)
190 break;
191 switch (res->action) {
192 case SHOW:
193 case SHOW_SUM:
194 done = show_summary_msg(&imsg);
195 break;
196 case SHOW_IFACE:
197 done = show_interface_msg(&imsg);
198 break;
199 case SHOW_IFACE_DTAIL:
200 done = show_interface_detail_msg(&imsg);
201 break;
202 case SHOW_IGMP:
203 done = show_igmp_msg(&imsg);
204 break;
205 case SHOW_NBR:
206 done = show_nbr_msg(&imsg);
207 break;
208 case SHOW_NBR_DTAIL:
209 done = show_nbr_detail_msg(&imsg);
210 break;
211 case SHOW_RIB:
212 done = show_rib_msg(&imsg);
213 break;
214 case SHOW_RIB_DTAIL:
215 done = show_rib_detail_msg(&imsg);
216 break;
217 case SHOW_MFC:
218 done = show_mfc_msg(&imsg);
219 break;
220 case SHOW_MFC_DTAIL:
221 done = show_mfc_detail_msg(&imsg);
222 break;
223 case NONE:
224 case LOG_VERBOSE:
225 case LOG_BRIEF:
226 case RELOAD:
227 break;
228 }
229 imsg_free(&imsg);
230 }
231 }
232 close(ctl_sock);
233 free(ibuf);
234
235 return (0);
236}
237
238int
239show_summary_msg(struct imsg *imsg)
240{
241 struct ctl_sum *sum;
242
243 switch (imsg->hdr.type) {
244 case IMSG_CTL_SHOW_SUM:
245 sum = imsg->data;
246 printf("Router ID: %s\n", inet_ntoa(sum->rtr_id));
247 printf("Hold time is %d sec(s)\n", sum->hold_time);
248 break;
249 case IMSG_CTL_END:
250 printf("\n");
251 return (1);
252 default:
253 break;
254 }
255
256 return (0);
257}
258
259int
260show_interface_msg(struct imsg *imsg)
261{
262 struct ctl_iface *iface;
263 char *netid;
264
265 switch (imsg->hdr.type) {
266 case IMSG_CTL_SHOW_IFACE:
267 iface = imsg->data;
268
269 if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr),
270 mask2prefixlen(iface->mask.s_addr)) == -1)
271 err(1, NULL((void *)0));
272 printf("%-11s %-18s %-10s %-10s %-10s %-8s %5d\n",
273 iface->name, netid, if_state_name(iface->state),
274 iface->probe_timer == 0 ? "00:00:00" :
275 fmt_timeframe_core(iface->probe_timer),
276 get_linkstate(iface->if_type, iface->linkstate),
277 iface->uptime == 0 ? "00:00:00" :
278 fmt_timeframe_core(iface->uptime), iface->group_cnt);
279 free(netid);
280 break;
281 case IMSG_CTL_END:
282 printf("\n");
283 return (1);
284 default:
285 break;
286 }
287
288 return (0);
289}
290
291int
292show_interface_detail_msg(struct imsg *imsg)
293{
294 struct ctl_iface *iface;
295
296 switch (imsg->hdr.type) {
297 case IMSG_CTL_SHOW_IFACE:
298 iface = imsg->data;
299
300 printf("\n");
301 printf("Interface %s, line protocol is %s\n",
302 iface->name, print_link(iface->flags));
303 printf(" Internet address %s/%d\n",
304 inet_ntoa(iface->addr),
305 mask2prefixlen(iface->mask.s_addr));
306 printf(" Linkstate %s\n",
307 get_linkstate(iface->if_type, iface->linkstate));
308 printf(" Network type %s, cost: %d\n",
309 if_type_name(iface->type), iface->metric);
310 printf(" State %s, querier ", if_state_name(iface->state));
311 if (iface->state == IF_STA_QUERIER0x02)
312 printf("%s\n", inet_ntoa(iface->addr));
313 else
314 printf("%s\n", inet_ntoa(iface->querier));
315 printf(" Generation ID %d\n", iface->gen_id);
316 printf(" Timer intervals configured, "
317 "probe %d, dead %d\n", iface->probe_interval,
318 iface->dead_interval);
319 if (iface->passive)
320 printf(" Passive interface (No Hellos)\n");
321 else if (iface->probe_timer < 0)
322 printf(" Hello timer not running\n");
323 else
324 printf(" Hello timer due in %s\n",
325 fmt_timeframe_core(iface->probe_timer));
326 printf(" Uptime %s\n", iface->uptime == 0 ?
327 "00:00:00" : fmt_timeframe_core(iface->uptime));
328 printf(" Adjacent neighbor count is "
329 "%d\n", iface->adj_cnt);
330 break;
331 case IMSG_CTL_END:
332 printf("\n");
333 return (1);
334 default:
335 break;
336 }
337
338 return (0);
339}
340
341int
342show_igmp_msg(struct imsg *imsg)
343{
344 struct ctl_iface *iface;
345 struct ctl_group *group;
346 char *netid;
347
348 switch (imsg->hdr.type) {
349 case IMSG_CTL_SHOW_IFACE:
350 iface = imsg->data;
351 if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr),
352 mask2prefixlen(iface->mask.s_addr)) == -1)
353 err(1, NULL((void *)0));
354 printf("\nInterface %s, address %s, state %s, groups %d\n",
355 iface->name, netid, if_state_name(iface->state),
356 iface->group_cnt);
357 free(netid);
358 printf(" %-16s %-10s %-10s %-10s\n", "Group", "State",
359 "DeadTimer", "Uptime");
360 break;
361 case IMSG_CTL_SHOW_IGMP:
362 group = imsg->data;
363 printf(" %-16s %-10s %-10s %-10s\n", inet_ntoa(group->addr),
364 group_state_name(group->state),
365 group->dead_timer == 0 ? "00:00:00" :
366 fmt_timeframe_core(group->dead_timer),
367 group->uptime == 0 ? "00:00:00" :
368 fmt_timeframe_core(group->uptime));
369 break;
370 case IMSG_CTL_END:
371 printf("\n");
372 return (1);
373 default:
374 break;
375 }
376
377 return (0);
378}
379
380const char *
381print_if_type(enum iface_type type)
382{
383 switch (type) {
384 case IF_TYPE_POINTOPOINT:
385 return ("POINTOPOINT");
386 case IF_TYPE_BROADCAST:
387 return ("BROADCAST");
388 default:
389 return ("UNKNOWN");
390 }
391}
392
393const char *
394print_nbr_state(int state)
395{
396 switch (state) {
397 case NBR_STA_DOWN0x01:
398 return ("DOWN");
399 case NBR_STA_1_WAY0x02:
400 return ("1-WAY");
401 case NBR_STA_2_WAY0x04:
402 return ("2-WAY");
403 default:
404 return ("UNKNOWN");
405 }
406}
407
408const char *
409print_link(int state)
410{
411 if (state & IFF_UP0x1)
412 return ("UP");
413 else
414 return ("DOWN");
415}
416
417#define TF_BUFS8 8
418#define TF_LEN9 9
419
420const char *
421fmt_timeframe(time_t t)
422{
423 if (t == 0)
424 return ("Never");
425 else
426 return (fmt_timeframe_core(time(NULL((void *)0)) - t));
427}
428
429const char *
430fmt_timeframe_core(time_t t)
431{
432 char *buf;
433 static char tfbuf[TF_BUFS8][TF_LEN9]; /* ring buffer */
434 static int idx = 0;
435 unsigned int sec, min, hrs, day;
436 unsigned long long week;
437
438 if (t == 0)
439 return ("Stopped");
440
441 buf = tfbuf[idx++];
442 if (idx == TF_BUFS8)
443 idx = 0;
444
445 week = t;
446
447 sec = week % 60;
448 week /= 60;
449 min = week % 60;
450 week /= 60;
451 hrs = week % 24;
452 week /= 24;
453 day = week % 7;
454 week /= 7;
455
456 if (week > 0)
457 snprintf(buf, TF_LEN9, "%02lluw%01ud%02uh", week, day, hrs);
458 else if (day > 0)
459 snprintf(buf, TF_LEN9, "%01ud%02uh%02um", day, hrs, min);
460 else
461 snprintf(buf, TF_LEN9, "%02u:%02u:%02u", hrs, min, sec);
462
463 return (buf);
464}
465
466/* prototype defined in dvmrpd.h and shared with the kroute.c version */
467u_int8_t
468mask2prefixlen(in_addr_t ina)
469{
470 if (ina == 0)
471 return (0);
472 else
473 return (33 - ffs(ntohl(ina)(__uint32_t)(__builtin_constant_p(ina) ? (__uint32_t)(((__uint32_t
)(ina) & 0xff) << 24 | ((__uint32_t)(ina) & 0xff00
) << 8 | ((__uint32_t)(ina) & 0xff0000) >> 8 |
((__uint32_t)(ina) & 0xff000000) >> 24) : __swap32md
(ina))
));
474}
475
476int
477show_nbr_msg(struct imsg *imsg)
478{
479 struct ctl_nbr *nbr;
480
481 switch (imsg->hdr.type) {
482 case IMSG_CTL_SHOW_NBR:
483 nbr = imsg->data;
484 printf("%-15s %-10s %-10s", inet_ntoa(nbr->id),
485 print_nbr_state(nbr->state),
486 fmt_timeframe_core(nbr->dead_timer));
487 printf("%-15s %-11s %s\n", inet_ntoa(nbr->addr),
488 nbr->name, fmt_timeframe_core(nbr->uptime));
489 break;
490 case IMSG_CTL_END:
491 printf("\n");
492 return (1);
493 default:
494 break;
495 }
496
497 return (0);
498}
499
500const char *
501print_dvmrp_options(u_int8_t opts)
502{
503 static char optbuf[32];
504
505 snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|%s",
506 opts & DVMRP_CAP_NETMASK0x20 ? "N" : "-",
507 opts & DVMRP_CAP_SNMP0x10 ? "S" : "-",
508 opts & DVMRP_CAP_MTRACE0x08 ? "M" : "-",
509 opts & DVMRP_CAP_GENID0x04 ? "G" : "-",
510 opts & DVMRP_CAP_PRUNE0x02 ? "P" : "-",
511 opts & DVMRP_CAP_LEAF0x01 ? "L" : "-");
512 return (optbuf);
513}
514
515int
516show_nbr_detail_msg(struct imsg *imsg)
517{
518 struct ctl_nbr *nbr;
519
520 switch (imsg->hdr.type) {
521 case IMSG_CTL_SHOW_NBR:
522 nbr = imsg->data;
Value stored to 'nbr' is never read
523 break;
524 case IMSG_CTL_END:
525 printf("\n");
526 return (1);
527 default:
528 break;
529 }
530
531 return (0);
532}
533
534int
535show_rib_msg(struct imsg *imsg)
536{
537 struct ctl_rt *rt;
538 char *dstnet;
539
540 switch (imsg->hdr.type) {
541 case IMSG_CTL_SHOW_RIB:
542 rt = imsg->data;
543 if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix),
544 rt->prefixlen) == -1)
545 err(1, NULL((void *)0));
546
547 printf("%-20s %-17s %-7d %-9s %9s\n", dstnet,
548 inet_ntoa(rt->nexthop),
549 rt->cost, rt->uptime == 0 ? "-" :
550 fmt_timeframe_core(rt->uptime),
551 rt->expire == 0 ? "00:00:00" :
552 fmt_timeframe_core(rt->expire));
553 free(dstnet);
554
555 break;
556 case IMSG_CTL_END:
557 printf("\n");
558 return (1);
559 default:
560 break;
561 }
562
563 return (0);
564}
565
566int
567show_rib_detail_msg(struct imsg *imsg)
568{
569
570 switch (imsg->hdr.type) {
571 case IMSG_CTL_SHOW_RIB:
572 break;
573 case IMSG_CTL_END:
574 printf("\n");
575 return (1);
576 default:
577 break;
578 }
579
580 return (0);
581}
582
583int
584show_mfc_msg(struct imsg *imsg)
585{
586 char iname[IF_NAMESIZE16];
587 char oname[IF_NAMESIZE16] = "-";
588 struct ctl_mfc *mfc;
589 int i;
590
591
592 switch (imsg->hdr.type) {
593 case IMSG_CTL_SHOW_MFC:
594 mfc = imsg->data;
595 if_indextoname(mfc->ifindex, iname);
596
597 /* search for first entry with ttl > 0 */
598 for (i = 0; i < MAXVIFS32; i++) {
599 if (mfc->ttls[i] > 0) {
600 if_indextoname(i, oname);
601 i++;
602 break;
603 }
604 }
605
606 /* display first entry with uptime */
607 printf("%-16s ", inet_ntoa(mfc->group));
608 printf("%-16s %-9s %-9s %-4d %-10s %-10s\n",
609 inet_ntoa(mfc->origin), iname, oname, mfc->ttls[i - 1],
610 mfc->uptime == 0 ? "-" : fmt_timeframe_core(mfc->uptime),
611 mfc->expire == 0 ? "-" : fmt_timeframe_core(mfc->expire));
612
613 /* display remaining entries with ttl > 0 */
614 for (; i < MAXVIFS32; i++) {
615 if (mfc->ttls[i] > 0) {
616 if_indextoname(i, oname);
617 printf("%43s %-9s %-4d\n", " ", oname,
618 mfc->ttls[i]);
619 }
620 }
621 break;
622 case IMSG_CTL_END:
623 printf("\n");
624 return (1);
625 default:
626 break;
627 }
628
629 return (0);
630}
631
632int
633show_mfc_detail_msg(struct imsg *imsg)
634{
635
636 switch (imsg->hdr.type) {
637 case IMSG_CTL_SHOW_MFC:
638 break;
639 case IMSG_CTL_END:
640 printf("\n");
641 return (1);
642 default:
643 break;
644 }
645
646 return (0);
647}
648
649const struct if_status_description
650 if_status_descriptions[] = LINK_STATE_DESCRIPTIONS{ { 0x06, 2, "no carrier" }, { 0x47, 2, "no network" }, { 0x17
, 2, "no carrier" }, { 0xf7, 2, "backup" }, { 0xf7, 4, "master"
}, { 0xf7, 5, "master" }, { 0xf7, 6, "master" }, { 0, 4, "active"
}, { 0, 5, "active" }, { 0, 6, "active" }, { 0, 0, "unknown"
}, { 0, 1, "invalid" }, { 0, 2, "down" }, { 0, 3, "keepalive down"
}, { 0, 0, ((void *)0) } }
;
651
652const char *
653get_linkstate(uint8_t if_type, int link_state)
654{
655 const struct if_status_description *p;
656 static char buf[8];
657
658 for (p = if_status_descriptions; p->ifs_string != NULL((void *)0); p++) {
659 if (LINK_STATE_DESC_MATCH(p, if_type, link_state)(((p)->ifs_type == (if_type) || (p)->ifs_type == 0) &&
(p)->ifs_state == (link_state))
)
660 return (p->ifs_string);
661 }
662 snprintf(buf, sizeof(buf), "[#%d]", link_state);
663 return (buf);
664}