1*f1b790a5Sclaudio /* $OpenBSD: ospfctl.c,v 1.73 2024/11/21 13:38:14 claudio 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 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 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); 109*f1b790a5Sclaudio if (imsgbuf_init(ibuf, ctl_sock) == -1) 110*f1b790a5Sclaudio err(1, NULL); 111b49634deSclaudio done = 0; 112b49634deSclaudio 113b49634deSclaudio /* process user request */ 114b49634deSclaudio switch (res->action) { 115b49634deSclaudio case NONE: 116b49634deSclaudio usage(); 117b49634deSclaudio /* not reached */ 118b49634deSclaudio case SHOW: 11959df52c7Snorby case SHOW_SUM: 1207f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 121b49634deSclaudio break; 122b49634deSclaudio case SHOW_IFACE: 12312bb42a0Snorby case SHOW_IFACE_DTAIL: 124b49634deSclaudio if (*res->ifname) { 125b49634deSclaudio ifidx = if_nametoindex(res->ifname); 126b49634deSclaudio if (ifidx == 0) 127b49634deSclaudio errx(1, "no such interface %s", res->ifname); 128b49634deSclaudio } 1297f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 130b49634deSclaudio &ifidx, sizeof(ifidx)); 131b49634deSclaudio break; 132b49634deSclaudio case SHOW_NBR: 133b49634deSclaudio case SHOW_NBR_DTAIL: 1347f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 135b49634deSclaudio break; 136b49634deSclaudio case SHOW_DB: 1377f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); 138b49634deSclaudio break; 139b49634deSclaudio case SHOW_DBBYAREA: 1407f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, 141b49634deSclaudio &res->addr, sizeof(res->addr)); 142b49634deSclaudio break; 14332286112Snorby case SHOW_DBEXT: 1447f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); 14532286112Snorby break; 14632286112Snorby case SHOW_DBNET: 1477f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); 14832286112Snorby break; 14932286112Snorby case SHOW_DBRTR: 1507f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); 15132286112Snorby break; 15232286112Snorby case SHOW_DBSELF: 1537f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); 15432286112Snorby break; 15532286112Snorby case SHOW_DBSUM: 1567f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); 15732286112Snorby break; 15832286112Snorby case SHOW_DBASBR: 1597f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); 16032286112Snorby break; 16197494e25Sclaudio case SHOW_DBOPAQ: 16297494e25Sclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_DB_OPAQ, 0, 0, -1, NULL, 0); 16397494e25Sclaudio break; 16437355230Snorby case SHOW_RIB: 16537355230Snorby case SHOW_RIB_DTAIL: 1667f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 16737355230Snorby break; 168c47b7f65Sclaudio case SHOW_FIB: 169c47b7f65Sclaudio if (!res->addr.s_addr) 1707f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 171c47b7f65Sclaudio &res->flags, sizeof(res->flags)); 172c47b7f65Sclaudio else 1737f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 174c47b7f65Sclaudio &res->addr, sizeof(res->addr)); 175c47b7f65Sclaudio break; 176c47b7f65Sclaudio case SHOW_FIB_IFACE: 1774c561fb6Sclaudio if (*res->ifname) 1787f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, 1794c561fb6Sclaudio res->ifname, sizeof(res->ifname)); 1804c561fb6Sclaudio else 1817f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); 182c47b7f65Sclaudio break; 18373a141beSclaudio case FIB: 18473a141beSclaudio errx(1, "fib couple|decouple"); 18573a141beSclaudio break; 18673a141beSclaudio case FIB_COUPLE: 1877f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); 18873a141beSclaudio printf("couple request sent.\n"); 18973a141beSclaudio done = 1; 19073a141beSclaudio break; 19173a141beSclaudio case FIB_DECOUPLE: 1927f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); 19373a141beSclaudio printf("decouple request sent.\n"); 19473a141beSclaudio done = 1; 19573a141beSclaudio break; 196119f0f1dSdlg case FIB_RELOAD: 197119f0f1dSdlg imsg_compose(ibuf, IMSG_CTL_FIB_RELOAD, 0, 0, -1, NULL, 0); 198119f0f1dSdlg printf("reload request sent.\n"); 199119f0f1dSdlg done = 1; 200119f0f1dSdlg break; 201c3319070Sclaudio case LOG_VERBOSE: 202c3319070Sclaudio verbose = 1; 203c3319070Sclaudio /* FALLTHROUGH */ 204c3319070Sclaudio case LOG_BRIEF: 205c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 206c3319070Sclaudio &verbose, sizeof(verbose)); 207c3319070Sclaudio printf("logging request sent.\n"); 208c3319070Sclaudio done = 1; 209c3319070Sclaudio break; 210b49634deSclaudio case RELOAD: 2117f472484Spyr imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 212b49634deSclaudio printf("reload request sent.\n"); 213b49634deSclaudio done = 1; 214b49634deSclaudio break; 215b49634deSclaudio } 216b49634deSclaudio 217dd7efffeSclaudio if (imsgbuf_flush(ibuf) == -1) 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) { 225668e5ba9Sclaudio if ((n = imsgbuf_read(ibuf)) == -1) 226ef2e27a1Sclaudio err(1, "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 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 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 * 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 * 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 * 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 * 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 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 56356babc06Sclaudio print_baudrate(u_int64_t baudrate) 564c47b7f65Sclaudio { 56587862bd3Sdenis static char buf[32]; 566c502c694Sdenis 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