1*c502c694Sdenis /* $OpenBSD: ospfctl.c,v 1.68 2020/05/20 11:11:24 denis Exp $ */
2b49634deSclaudio
3b49634deSclaudio /*
4b49634deSclaudio * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
537355230Snorby * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
6b49634deSclaudio * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
7b49634deSclaudio *
8b49634deSclaudio * Permission to use, copy, modify, and distribute this software for any
9b49634deSclaudio * purpose with or without fee is hereby granted, provided that the above
10b49634deSclaudio * copyright notice and this permission notice appear in all copies.
11b49634deSclaudio *
12b49634deSclaudio * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13b49634deSclaudio * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14b49634deSclaudio * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15b49634deSclaudio * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16b49634deSclaudio * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17b49634deSclaudio * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18b49634deSclaudio * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19b49634deSclaudio */
20b49634deSclaudio
21b49634deSclaudio #include <sys/types.h>
22b49634deSclaudio #include <sys/socket.h>
23b49634deSclaudio #include <sys/un.h>
24b49634deSclaudio #include <netinet/in.h>
25b49634deSclaudio #include <arpa/inet.h>
26c47b7f65Sclaudio #include <net/if_media.h>
27c47b7f65Sclaudio #include <net/if_types.h>
28b49634deSclaudio
29b49634deSclaudio #include <err.h>
30c0dbf5cfSsthen #include <errno.h>
31b49634deSclaudio #include <stdio.h>
32b49634deSclaudio #include <stdlib.h>
33b49634deSclaudio #include <string.h>
34b49634deSclaudio #include <unistd.h>
35b49634deSclaudio
36b49634deSclaudio #include "ospf.h"
37b49634deSclaudio #include "ospfd.h"
3887862bd3Sdenis #include "ospfctl.h"
39b49634deSclaudio #include "ospfe.h"
40b49634deSclaudio #include "parser.h"
41b49634deSclaudio
42cbb557dbShenning __dead void usage(void);
4387862bd3Sdenis
4487862bd3Sdenis int show(struct imsg *, struct parse_result *);
45b49634deSclaudio
46b49634deSclaudio struct imsgbuf *ibuf;
4787862bd3Sdenis const struct output *output = &show_output;
48b49634deSclaudio
49cbb557dbShenning __dead void
usage(void)50b49634deSclaudio usage(void)
51b49634deSclaudio {
52b49634deSclaudio extern char *__progname;
53b49634deSclaudio
54d1b94773Sreyk fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n",
55d1b94773Sreyk __progname);
56b49634deSclaudio exit(1);
57b49634deSclaudio }
58b49634deSclaudio
59b49634deSclaudio int
main(int argc,char * argv[])60b49634deSclaudio main(int argc, char *argv[])
61b49634deSclaudio {
62b49634deSclaudio struct sockaddr_un sun;
63b49634deSclaudio struct parse_result *res;
64b49634deSclaudio struct imsg imsg;
65b49634deSclaudio unsigned int ifidx = 0;
66ec107b41Sremi int ctl_sock, r;
67b49634deSclaudio int done = 0;
68c3319070Sclaudio int n, verbose = 0;
69d1b94773Sreyk int ch;
70d1b94773Sreyk char *sockname;
71d1b94773Sreyk
72ec107b41Sremi r = getrtable();
73ec107b41Sremi if (asprintf(&sockname, "%s.%d", OSPFD_SOCKET, r) == -1)
74ec107b41Sremi err(1, "asprintf");
75ec107b41Sremi
76d1b94773Sreyk while ((ch = getopt(argc, argv, "s:")) != -1) {
77d1b94773Sreyk switch (ch) {
78d1b94773Sreyk case 's':
79d1b94773Sreyk sockname = optarg;
80d1b94773Sreyk break;
81d1b94773Sreyk default:
82d1b94773Sreyk usage();
83d1b94773Sreyk /* NOTREACHED */
84d1b94773Sreyk }
85d1b94773Sreyk }
86d1b94773Sreyk argc -= optind;
87d1b94773Sreyk argv += optind;
88b49634deSclaudio
89b49634deSclaudio /* parse options */
90d1b94773Sreyk if ((res = parse(argc, argv)) == NULL)
91b49634deSclaudio exit(1);
92b49634deSclaudio
93b49634deSclaudio /* connect to ospfd control socket */
94b49634deSclaudio if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
95b49634deSclaudio err(1, "socket");
96b49634deSclaudio
97b49634deSclaudio bzero(&sun, sizeof(sun));
98b49634deSclaudio sun.sun_family = AF_UNIX;
99d1b94773Sreyk strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path));
100cee51daaSflorian
101b49634deSclaudio if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
102d1b94773Sreyk err(1, "connect: %s", sockname);
103b49634deSclaudio
10468598ea0Sderaadt if (pledge("stdio", NULL) == -1)
10568598ea0Sderaadt err(1, "pledge");
10668598ea0Sderaadt
107b49634deSclaudio if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
108d2141824Sstevesk err(1, NULL);
1097b4c0c10Seric imsg_init(ibuf, ctl_sock);
110b49634deSclaudio done = 0;
111b49634deSclaudio
112b49634deSclaudio /* process user request */
113b49634deSclaudio switch (res->action) {
114b49634deSclaudio case NONE:
115b49634deSclaudio usage();
116b49634deSclaudio /* not reached */
117b49634deSclaudio case SHOW:
11859df52c7Snorby case SHOW_SUM:
1197f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
120b49634deSclaudio break;
121b49634deSclaudio case SHOW_IFACE:
12212bb42a0Snorby case SHOW_IFACE_DTAIL:
123b49634deSclaudio if (*res->ifname) {
124b49634deSclaudio ifidx = if_nametoindex(res->ifname);
125b49634deSclaudio if (ifidx == 0)
126b49634deSclaudio errx(1, "no such interface %s", res->ifname);
127b49634deSclaudio }
1287f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1,
129b49634deSclaudio &ifidx, sizeof(ifidx));
130b49634deSclaudio break;
131b49634deSclaudio case SHOW_NBR:
132b49634deSclaudio case SHOW_NBR_DTAIL:
1337f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
134b49634deSclaudio break;
135b49634deSclaudio case SHOW_DB:
1367f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0);
137b49634deSclaudio break;
138b49634deSclaudio case SHOW_DBBYAREA:
1397f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1,
140b49634deSclaudio &res->addr, sizeof(res->addr));
141b49634deSclaudio break;
14232286112Snorby case SHOW_DBEXT:
1437f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0);
14432286112Snorby break;
14532286112Snorby case SHOW_DBNET:
1467f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0);
14732286112Snorby break;
14832286112Snorby case SHOW_DBRTR:
1497f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0);
15032286112Snorby break;
15132286112Snorby case SHOW_DBSELF:
1527f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0);
15332286112Snorby break;
15432286112Snorby case SHOW_DBSUM:
1557f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0);
15632286112Snorby break;
15732286112Snorby case SHOW_DBASBR:
1587f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0);
15932286112Snorby break;
16097494e25Sclaudio case SHOW_DBOPAQ:
16197494e25Sclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_DB_OPAQ, 0, 0, -1, NULL, 0);
16297494e25Sclaudio break;
16337355230Snorby case SHOW_RIB:
16437355230Snorby case SHOW_RIB_DTAIL:
1657f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0);
16637355230Snorby break;
167c47b7f65Sclaudio case SHOW_FIB:
168c47b7f65Sclaudio if (!res->addr.s_addr)
1697f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1,
170c47b7f65Sclaudio &res->flags, sizeof(res->flags));
171c47b7f65Sclaudio else
1727f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1,
173c47b7f65Sclaudio &res->addr, sizeof(res->addr));
174c47b7f65Sclaudio break;
175c47b7f65Sclaudio case SHOW_FIB_IFACE:
1764c561fb6Sclaudio if (*res->ifname)
1777f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1,
1784c561fb6Sclaudio res->ifname, sizeof(res->ifname));
1794c561fb6Sclaudio else
1807f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0);
181c47b7f65Sclaudio break;
18273a141beSclaudio case FIB:
18373a141beSclaudio errx(1, "fib couple|decouple");
18473a141beSclaudio break;
18573a141beSclaudio case FIB_COUPLE:
1867f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0);
18773a141beSclaudio printf("couple request sent.\n");
18873a141beSclaudio done = 1;
18973a141beSclaudio break;
19073a141beSclaudio case FIB_DECOUPLE:
1917f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0);
19273a141beSclaudio printf("decouple request sent.\n");
19373a141beSclaudio done = 1;
19473a141beSclaudio break;
195119f0f1dSdlg case FIB_RELOAD:
196119f0f1dSdlg imsg_compose(ibuf, IMSG_CTL_FIB_RELOAD, 0, 0, -1, NULL, 0);
197119f0f1dSdlg printf("reload request sent.\n");
198119f0f1dSdlg done = 1;
199119f0f1dSdlg break;
200c3319070Sclaudio case LOG_VERBOSE:
201c3319070Sclaudio verbose = 1;
202c3319070Sclaudio /* FALLTHROUGH */
203c3319070Sclaudio case LOG_BRIEF:
204c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1,
205c3319070Sclaudio &verbose, sizeof(verbose));
206c3319070Sclaudio printf("logging request sent.\n");
207c3319070Sclaudio done = 1;
208c3319070Sclaudio break;
209b49634deSclaudio case RELOAD:
2107f472484Spyr imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
211b49634deSclaudio printf("reload request sent.\n");
212b49634deSclaudio done = 1;
213b49634deSclaudio break;
214b49634deSclaudio }
215b49634deSclaudio
216b49634deSclaudio while (ibuf->w.queued)
217c0dbf5cfSsthen if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
218b49634deSclaudio err(1, "write error");
219b49634deSclaudio
22087862bd3Sdenis /* no output for certain commands such as log verbose */
22187862bd3Sdenis if (!done) {
22287862bd3Sdenis output->head(res);
22387862bd3Sdenis
224b49634deSclaudio while (!done) {
225cc37529cSclaudio if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
226b49634deSclaudio errx(1, "imsg_read error");
227b49634deSclaudio if (n == 0)
228b49634deSclaudio errx(1, "pipe closed");
229b49634deSclaudio
230b49634deSclaudio while (!done) {
231b49634deSclaudio if ((n = imsg_get(ibuf, &imsg)) == -1)
232b49634deSclaudio errx(1, "imsg_get error");
233b49634deSclaudio if (n == 0)
234b49634deSclaudio break;
23587862bd3Sdenis
23687862bd3Sdenis done = show(&imsg, res);
237b49634deSclaudio imsg_free(&imsg);
238b49634deSclaudio }
239b49634deSclaudio }
24087862bd3Sdenis
24187862bd3Sdenis output->tail();
24287862bd3Sdenis }
24387862bd3Sdenis
244b49634deSclaudio close(ctl_sock);
245b49634deSclaudio free(ibuf);
246b49634deSclaudio
247b49634deSclaudio return (0);
248b49634deSclaudio }
249b49634deSclaudio
250b49634deSclaudio int
show(struct imsg * imsg,struct parse_result * res)25187862bd3Sdenis show(struct imsg *imsg, struct parse_result *res)
252b49634deSclaudio {
25359df52c7Snorby struct ctl_sum *sum;
25459df52c7Snorby struct ctl_sum_area *sumarea;
25587862bd3Sdenis struct ctl_iface *ctliface;
25687862bd3Sdenis struct ctl_nbr *nbr;
25787862bd3Sdenis struct ctl_rt *rt;
25887862bd3Sdenis struct kroute *k;
25987862bd3Sdenis struct kif *kif;
26087862bd3Sdenis static struct in_addr area_id;
26187862bd3Sdenis struct area *area;
26287862bd3Sdenis static u_int8_t lasttype;
26387862bd3Sdenis static char ifname[IF_NAMESIZE];
26487862bd3Sdenis struct iface *iface;
26587862bd3Sdenis struct lsa *lsa;
26687862bd3Sdenis struct lsa_hdr *lsa_hdr;
26759df52c7Snorby
26859df52c7Snorby switch (imsg->hdr.type) {
26959df52c7Snorby case IMSG_CTL_SHOW_SUM:
27059df52c7Snorby sum = imsg->data;
27187862bd3Sdenis output->summary(sum);
27259df52c7Snorby break;
27359df52c7Snorby case IMSG_CTL_SHOW_SUM_AREA:
27459df52c7Snorby sumarea = imsg->data;
27587862bd3Sdenis output->summary_area(sumarea);
27687862bd3Sdenis break;
27787862bd3Sdenis case IMSG_CTL_SHOW_INTERFACE:
27887862bd3Sdenis ctliface = imsg->data;
27987862bd3Sdenis if(res->action == SHOW_IFACE_DTAIL)
28087862bd3Sdenis output->interface(ctliface, 1);
28187862bd3Sdenis else
28287862bd3Sdenis output->interface(ctliface, 0);
28387862bd3Sdenis break;
28487862bd3Sdenis case IMSG_CTL_SHOW_NBR:
28587862bd3Sdenis nbr = imsg->data;
28687862bd3Sdenis if(res->action == SHOW_NBR_DTAIL)
28787862bd3Sdenis output->neighbor(nbr, 1);
28887862bd3Sdenis else
28987862bd3Sdenis output->neighbor(nbr, 0);
29087862bd3Sdenis break;
29187862bd3Sdenis case IMSG_CTL_SHOW_RIB:
29287862bd3Sdenis rt = imsg->data;
29387862bd3Sdenis if(res->action == SHOW_RIB_DTAIL)
29487862bd3Sdenis output->rib(rt, 1);
29587862bd3Sdenis else
29687862bd3Sdenis output->rib(rt, 0);
29787862bd3Sdenis break;
29887862bd3Sdenis case IMSG_CTL_KROUTE:
29987862bd3Sdenis if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute))
30087862bd3Sdenis errx(1, "wrong imsg len");
30187862bd3Sdenis k = imsg->data;
30287862bd3Sdenis output->fib(k);
30387862bd3Sdenis break;
30487862bd3Sdenis case IMSG_CTL_IFINFO:
30587862bd3Sdenis kif = imsg->data;
30687862bd3Sdenis output->fib_interface(kif);
30787862bd3Sdenis break;
30887862bd3Sdenis case IMSG_CTL_SHOW_DB_EXT:
30987862bd3Sdenis case IMSG_CTL_SHOW_DB_NET:
31087862bd3Sdenis case IMSG_CTL_SHOW_DB_RTR:
31187862bd3Sdenis case IMSG_CTL_SHOW_DB_SUM:
31287862bd3Sdenis case IMSG_CTL_SHOW_DB_ASBR:
31387862bd3Sdenis case IMSG_CTL_SHOW_DB_OPAQ:
31487862bd3Sdenis lsa = imsg->data;
31587862bd3Sdenis output->db(lsa, area_id, lasttype, ifname);
31687862bd3Sdenis lasttype = lsa->hdr.type;
31787862bd3Sdenis break;
31887862bd3Sdenis case IMSG_CTL_SHOW_DATABASE:
31987862bd3Sdenis case IMSG_CTL_SHOW_DB_SELF:
32087862bd3Sdenis lsa_hdr = imsg->data;
32187862bd3Sdenis output->db_simple(lsa_hdr, area_id, lasttype, ifname);
32287862bd3Sdenis lasttype = lsa_hdr->type;
32387862bd3Sdenis break;
32487862bd3Sdenis case IMSG_CTL_AREA:
32587862bd3Sdenis area = imsg->data;
32687862bd3Sdenis area_id = area->id;
32787862bd3Sdenis lasttype = 0;
32887862bd3Sdenis break;
32987862bd3Sdenis case IMSG_CTL_IFACE:
33087862bd3Sdenis iface = imsg->data;
33187862bd3Sdenis strlcpy(ifname, iface->name, sizeof(ifname));
33287862bd3Sdenis lasttype = 0;
33359df52c7Snorby break;
33459df52c7Snorby case IMSG_CTL_END:
33559df52c7Snorby return (1);
33659df52c7Snorby default:
33787862bd3Sdenis warnx("unknown imsg %d received", imsg->hdr.type);
33859df52c7Snorby break;
33959df52c7Snorby }
340b49634deSclaudio
341b49634deSclaudio return (0);
342b49634deSclaudio }
343b49634deSclaudio
34418ffdd94Sstsp uint64_t
get_ifms_type(uint8_t if_type)34518ffdd94Sstsp get_ifms_type(uint8_t if_type)
3463caca30dSnorby {
34718ffdd94Sstsp switch (if_type) {
3483caca30dSnorby case IFT_ETHER:
3493caca30dSnorby return (IFM_ETHER);
3503caca30dSnorby case IFT_FDDI:
3513caca30dSnorby return (IFM_FDDI);
3523caca30dSnorby case IFT_CARP:
3533caca30dSnorby return (IFM_CARP);
354a5bcf77aSclaudio case IFT_PPP:
355a5bcf77aSclaudio return (IFM_TDM);
3563caca30dSnorby default:
3573caca30dSnorby return (0);
3583caca30dSnorby }
3593caca30dSnorby }
3603caca30dSnorby
361b49634deSclaudio const char *
print_link(int state)362b49634deSclaudio print_link(int state)
363b49634deSclaudio {
364b49634deSclaudio if (state & IFF_UP)
365b49634deSclaudio return ("UP");
366b49634deSclaudio else
367b49634deSclaudio return ("DOWN");
368b49634deSclaudio }
369b49634deSclaudio
370b49634deSclaudio #define TF_BUFS 8
371b49634deSclaudio #define TF_LEN 9
372b49634deSclaudio
373b49634deSclaudio const char *
fmt_timeframe_core(time_t t)374b49634deSclaudio fmt_timeframe_core(time_t t)
375b49634deSclaudio {
376b49634deSclaudio char *buf;
377b49634deSclaudio static char tfbuf[TF_BUFS][TF_LEN];/* ring buffer */
378b49634deSclaudio static int idx = 0;
379035b0708Sgilles unsigned int sec, min, hrs, day;
380035b0708Sgilles unsigned long long week;
381b49634deSclaudio
382b49634deSclaudio if (t == 0)
38311c16ffaSnorby return ("00:00:00");
384b49634deSclaudio
385b49634deSclaudio buf = tfbuf[idx++];
386b49634deSclaudio if (idx == TF_BUFS)
387b49634deSclaudio idx = 0;
388b49634deSclaudio
389b49634deSclaudio week = t;
390b49634deSclaudio
391b49634deSclaudio sec = week % 60;
392b49634deSclaudio week /= 60;
393b49634deSclaudio min = week % 60;
394b49634deSclaudio week /= 60;
395b49634deSclaudio hrs = week % 24;
396b49634deSclaudio week /= 24;
397b49634deSclaudio day = week % 7;
398b49634deSclaudio week /= 7;
399b49634deSclaudio
400b49634deSclaudio if (week > 0)
401035b0708Sgilles snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs);
402b49634deSclaudio else if (day > 0)
403b49634deSclaudio snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
404b49634deSclaudio else
405b49634deSclaudio snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
406b49634deSclaudio
407b49634deSclaudio return (buf);
408b49634deSclaudio }
409b49634deSclaudio
410b49634deSclaudio const char *
log_id(u_int32_t id)411b49634deSclaudio log_id(u_int32_t id)
412b49634deSclaudio {
413b49634deSclaudio static char buf[48];
414b49634deSclaudio struct in_addr addr;
415b49634deSclaudio
416b49634deSclaudio addr.s_addr = id;
417b49634deSclaudio
418b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL)
419b49634deSclaudio return ("?");
420b49634deSclaudio else
421b49634deSclaudio return (buf);
422b49634deSclaudio }
423b49634deSclaudio
424b49634deSclaudio const char *
log_adv_rtr(u_int32_t adv_rtr)425b49634deSclaudio log_adv_rtr(u_int32_t adv_rtr)
426b49634deSclaudio {
427b49634deSclaudio static char buf[48];
428b49634deSclaudio struct in_addr addr;
429b49634deSclaudio
430b49634deSclaudio addr.s_addr = adv_rtr;
431b49634deSclaudio
432b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL)
433b49634deSclaudio return ("?");
434b49634deSclaudio else
435b49634deSclaudio return (buf);
436b49634deSclaudio }
437b49634deSclaudio
4383ec0d80eSclaudio /* prototype defined in ospfd.h and shared with the kroute.c version */
439b49634deSclaudio u_int8_t
mask2prefixlen(in_addr_t ina)4403ec0d80eSclaudio mask2prefixlen(in_addr_t ina)
441b49634deSclaudio {
4423ec0d80eSclaudio if (ina == 0)
443b49634deSclaudio return (0);
444b49634deSclaudio else
4453ec0d80eSclaudio return (33 - ffs(ntohl(ina)));
446b49634deSclaudio }
447b49634deSclaudio
44832286112Snorby char *
print_ls_type(u_int8_t type)44932286112Snorby print_ls_type(u_int8_t type)
45032286112Snorby {
45132286112Snorby switch (type) {
45232286112Snorby case LSA_TYPE_ROUTER:
45332286112Snorby return ("Router");
45432286112Snorby case LSA_TYPE_NETWORK:
45532286112Snorby return ("Network");
45632286112Snorby case LSA_TYPE_SUM_NETWORK:
45732286112Snorby return ("Summary (Network)");
45832286112Snorby case LSA_TYPE_SUM_ROUTER:
45932286112Snorby return ("Summary (Router)");
46032286112Snorby case LSA_TYPE_EXTERNAL:
46132286112Snorby return ("AS External");
46297494e25Sclaudio case LSA_TYPE_LINK_OPAQ:
46397494e25Sclaudio return ("Type-9 Opaque");
46497494e25Sclaudio case LSA_TYPE_AREA_OPAQ:
46597494e25Sclaudio return ("Type-10 Opaque");
46697494e25Sclaudio case LSA_TYPE_AS_OPAQ:
46797494e25Sclaudio return ("Type-11 Opaque");
46832286112Snorby default:
46932286112Snorby return ("Unknown");
47032286112Snorby }
47132286112Snorby }
47232286112Snorby
47332286112Snorby char *
print_rtr_link_type(u_int8_t type)47432286112Snorby print_rtr_link_type(u_int8_t type)
47532286112Snorby {
47632286112Snorby switch (type) {
47732286112Snorby case LINK_TYPE_POINTTOPOINT:
47832286112Snorby return ("Point-to-Point");
47932286112Snorby case LINK_TYPE_TRANSIT_NET:
48032286112Snorby return ("Transit Network");
48132286112Snorby case LINK_TYPE_STUB_NET:
48232286112Snorby return ("Stub Network");
48332286112Snorby case LINK_TYPE_VIRTUAL:
48432286112Snorby return ("Virtual Link");
48532286112Snorby default:
48632286112Snorby return ("Unknown");
48732286112Snorby }
48832286112Snorby }
48932286112Snorby
49032286112Snorby const char *
print_ospf_flags(u_int8_t opts)49132286112Snorby print_ospf_flags(u_int8_t opts)
49232286112Snorby {
49332286112Snorby static char optbuf[32];
49432286112Snorby
49532286112Snorby snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s",
49632286112Snorby opts & OSPF_RTR_V ? "V" : "-",
49732286112Snorby opts & OSPF_RTR_E ? "E" : "-",
49832286112Snorby opts & OSPF_RTR_B ? "B" : "-");
49932286112Snorby return (optbuf);
50032286112Snorby }
50132286112Snorby
502b49634deSclaudio const char *
print_ospf_options(u_int8_t opts)503b49634deSclaudio print_ospf_options(u_int8_t opts)
504b49634deSclaudio {
505b49634deSclaudio static char optbuf[32];
506b49634deSclaudio
50797494e25Sclaudio snprintf(optbuf, sizeof(optbuf), "%s|%s|%s|%s|%s|%s|%s|%s",
50897494e25Sclaudio opts & OSPF_OPTION_DN ? "DN" : "-",
50997494e25Sclaudio opts & OSPF_OPTION_O ? "O" : "-",
510b49634deSclaudio opts & OSPF_OPTION_DC ? "DC" : "-",
511b49634deSclaudio opts & OSPF_OPTION_EA ? "EA" : "-",
512b49634deSclaudio opts & OSPF_OPTION_NP ? "N/P" : "-",
513b49634deSclaudio opts & OSPF_OPTION_MC ? "MC" : "-",
51497494e25Sclaudio opts & OSPF_OPTION_E ? "E" : "-",
51597494e25Sclaudio opts & OSPF_OPTION_MT ? "MT" : "-");
516b49634deSclaudio return (optbuf);
517b49634deSclaudio }
518b49634deSclaudio
51991e3b0aeSnorby const char *
print_ospf_rtr_flags(u_int8_t opts)52091e3b0aeSnorby print_ospf_rtr_flags(u_int8_t opts)
52191e3b0aeSnorby {
52291e3b0aeSnorby static char optbuf[32];
52391e3b0aeSnorby
52491e3b0aeSnorby snprintf(optbuf, sizeof(optbuf), "%s%s%s",
52591e3b0aeSnorby opts & OSPF_RTR_E ? "AS" : "",
52691e3b0aeSnorby opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "",
52791e3b0aeSnorby opts & OSPF_RTR_B ? "ABR" : "");
52891e3b0aeSnorby return (optbuf);
52937355230Snorby }
53037355230Snorby
5310f617141Sclaudio const struct if_status_description
5320f617141Sclaudio if_status_descriptions[] = LINK_STATE_DESCRIPTIONS;
533c47b7f65Sclaudio const struct ifmedia_description
534c47b7f65Sclaudio ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS;
535c47b7f65Sclaudio
536c47b7f65Sclaudio const char *
get_media_descr(uint64_t media_type)537e5605ae3Sderaadt get_media_descr(uint64_t media_type)
538c47b7f65Sclaudio {
539c47b7f65Sclaudio const struct ifmedia_description *p;
540c47b7f65Sclaudio
541c47b7f65Sclaudio for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++)
542c47b7f65Sclaudio if (media_type == p->ifmt_word)
543c47b7f65Sclaudio return (p->ifmt_string);
544c47b7f65Sclaudio
545a5bcf77aSclaudio return ("unknown");
546c47b7f65Sclaudio }
547c47b7f65Sclaudio
548c47b7f65Sclaudio const char *
get_linkstate(uint8_t if_type,int link_state)54918ffdd94Sstsp get_linkstate(uint8_t if_type, int link_state)
550c47b7f65Sclaudio {
5510f617141Sclaudio const struct if_status_description *p;
5520f617141Sclaudio static char buf[8];
553c47b7f65Sclaudio
5540f617141Sclaudio for (p = if_status_descriptions; p->ifs_string != NULL; p++) {
55518ffdd94Sstsp if (LINK_STATE_DESC_MATCH(p, if_type, link_state))
5560f617141Sclaudio return (p->ifs_string);
557c47b7f65Sclaudio }
5580f617141Sclaudio snprintf(buf, sizeof(buf), "[#%d]", link_state);
5590f617141Sclaudio return (buf);
560c47b7f65Sclaudio }
561c47b7f65Sclaudio
56287862bd3Sdenis const char *
print_baudrate(u_int64_t baudrate)56356babc06Sclaudio print_baudrate(u_int64_t baudrate)
564c47b7f65Sclaudio {
56587862bd3Sdenis static char buf[32];
566*c502c694Sdenis
567c47b7f65Sclaudio if (baudrate > IF_Gbps(1))
56887862bd3Sdenis snprintf(buf, sizeof(buf), "%llu GBit/s", baudrate / IF_Gbps(1));
569c47b7f65Sclaudio else if (baudrate > IF_Mbps(1))
57087862bd3Sdenis snprintf(buf, sizeof(buf), "%llu MBit/s", baudrate / IF_Mbps(1));
571c47b7f65Sclaudio else if (baudrate > IF_Kbps(1))
57287862bd3Sdenis snprintf(buf, sizeof(buf), "%llu KBit/s", baudrate / IF_Kbps(1));
573c47b7f65Sclaudio else
57487862bd3Sdenis snprintf(buf, sizeof(buf), "%llu Bit/s", baudrate);
57587862bd3Sdenis return (buf);
576c47b7f65Sclaudio }
577