1*f1b790a5Sclaudio /* $OpenBSD: ldpctl.c,v 1.37 2024/11/21 13:38:14 claudio Exp $ 2ab0c2486Smichele * 3ab0c2486Smichele * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> 4ab0c2486Smichele * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 5ab0c2486Smichele * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> 6ab0c2486Smichele * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> 7ab0c2486Smichele * 8ab0c2486Smichele * Permission to use, copy, modify, and distribute this software for any 9ab0c2486Smichele * purpose with or without fee is hereby granted, provided that the above 10ab0c2486Smichele * copyright notice and this permission notice appear in all copies. 11ab0c2486Smichele * 12ab0c2486Smichele * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13ab0c2486Smichele * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14ab0c2486Smichele * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15ab0c2486Smichele * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16ab0c2486Smichele * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17ab0c2486Smichele * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18ab0c2486Smichele * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19ab0c2486Smichele */ 20ab0c2486Smichele 21ab0c2486Smichele #include <sys/types.h> 22ab0c2486Smichele #include <sys/socket.h> 23ab0c2486Smichele #include <sys/un.h> 24ab0c2486Smichele #include <netinet/in.h> 25ab0c2486Smichele #include <arpa/inet.h> 26ab0c2486Smichele #include <net/if_media.h> 27ab0c2486Smichele #include <net/if_types.h> 28ab0c2486Smichele #include <netmpls/mpls.h> 29ab0c2486Smichele 30ab0c2486Smichele #include <err.h> 31397afdbcSderaadt #include <errno.h> 32ab0c2486Smichele #include <stdio.h> 33ab0c2486Smichele #include <stdlib.h> 34ab0c2486Smichele #include <string.h> 35ab0c2486Smichele #include <unistd.h> 36bdfaf4b1Sderaadt #include <limits.h> 37ab0c2486Smichele 38ab0c2486Smichele #include "ldp.h" 39ab0c2486Smichele #include "ldpd.h" 40ab0c2486Smichele #include "ldpe.h" 416fb6d103Srenato #include "log.h" 42ab0c2486Smichele #include "parser.h" 43ab0c2486Smichele 44ab0c2486Smichele __dead void usage(void); 45ab0c2486Smichele const char *fmt_timeframe_core(time_t); 460f882be7Sstsp const char *get_linkstate(uint8_t, int); 476fb6d103Srenato int show_interface_msg(struct imsg *, struct parse_result *); 486fb6d103Srenato int show_discovery_msg(struct imsg *, struct parse_result *); 490f882be7Sstsp uint64_t get_ifms_type(uint8_t); 506fb6d103Srenato int show_lib_msg(struct imsg *, struct parse_result *); 516fb6d103Srenato int show_nbr_msg(struct imsg *, struct parse_result *); 5292dd8dc8Sclaudio void show_fib_head(void); 536fb6d103Srenato int show_fib_msg(struct imsg *, struct parse_result *); 54ab0c2486Smichele void show_interface_head(void); 5592dd8dc8Sclaudio int show_fib_interface_msg(struct imsg *); 56a94c7fd0Srenato int show_l2vpn_pw_msg(struct imsg *); 57a94c7fd0Srenato int show_l2vpn_binding_msg(struct imsg *); 58e5605ae3Sderaadt const char *get_media_descr(uint64_t); 596c1e7e28Srenato void print_baudrate(uint64_t); 60ab0c2486Smichele 61ab0c2486Smichele struct imsgbuf *ibuf; 62ab0c2486Smichele 63ab0c2486Smichele __dead void 64ab0c2486Smichele usage(void) 65ab0c2486Smichele { 66ab0c2486Smichele extern char *__progname; 67ab0c2486Smichele 68ab0c2486Smichele fprintf(stderr, "usage: %s command [argument ...]\n", __progname); 69ab0c2486Smichele exit(1); 70ab0c2486Smichele } 71ab0c2486Smichele 72ab0c2486Smichele int 73ab0c2486Smichele main(int argc, char *argv[]) 74ab0c2486Smichele { 75ab0c2486Smichele struct sockaddr_un sun; 76ab0c2486Smichele struct parse_result *res; 77ab0c2486Smichele struct imsg imsg; 78ab0c2486Smichele unsigned int ifidx = 0; 796fb6d103Srenato struct kroute kr; 80ab0c2486Smichele int ctl_sock; 81c3319070Sclaudio int done = 0, verbose = 0; 82ab0c2486Smichele int n; 833f117ed9Srenato struct ctl_nbr nbr; 84ab0c2486Smichele 85ab0c2486Smichele /* parse options */ 86ab0c2486Smichele if ((res = parse(argc - 1, argv + 1)) == NULL) 87ab0c2486Smichele exit(1); 88ab0c2486Smichele 89ab0c2486Smichele /* connect to ldpd control socket */ 90ab0c2486Smichele if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 91ab0c2486Smichele err(1, "socket"); 92ab0c2486Smichele 9324d93a00Srenato memset(&sun, 0, sizeof(sun)); 94ab0c2486Smichele sun.sun_family = AF_UNIX; 95ab0c2486Smichele strlcpy(sun.sun_path, LDPD_SOCKET, sizeof(sun.sun_path)); 96ab0c2486Smichele if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 97ab0c2486Smichele err(1, "connect: %s", LDPD_SOCKET); 98ab0c2486Smichele 997ce073efSrenato if (pledge("stdio", NULL) == -1) 1007ce073efSrenato err(1, "pledge"); 1017ce073efSrenato 102ab0c2486Smichele if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 103ab0c2486Smichele err(1, NULL); 104*f1b790a5Sclaudio if (imsgbuf_init(ibuf, ctl_sock) == -1) 105*f1b790a5Sclaudio err(1, NULL); 106ab0c2486Smichele done = 0; 107ab0c2486Smichele 108ab0c2486Smichele /* process user request */ 109ab0c2486Smichele switch (res->action) { 110ab0c2486Smichele case NONE: 111ab0c2486Smichele usage(); 112ab0c2486Smichele /* not reached */ 113ab0c2486Smichele case SHOW: 114ab0c2486Smichele case SHOW_IFACE: 1156fb6d103Srenato printf("%-4s %-11s %-6s %-10s %-8s %-12s %3s\n", 1166fb6d103Srenato "AF", "Interface", "State", "Linkstate", "Uptime", 117905cf379Sclaudio "Hello Timers", "ac"); 118ab0c2486Smichele if (*res->ifname) { 119ab0c2486Smichele ifidx = if_nametoindex(res->ifname); 120ab0c2486Smichele if (ifidx == 0) 121ab0c2486Smichele errx(1, "no such interface %s", res->ifname); 122ab0c2486Smichele } 12302ff519fSmichele imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 124ab0c2486Smichele &ifidx, sizeof(ifidx)); 125ab0c2486Smichele break; 126d50436bbSclaudio case SHOW_DISC: 1276fb6d103Srenato printf("%-4s %-15s %-8s %-15s %9s\n", 1286fb6d103Srenato "AF", "ID", "Type", "Source", "Holdtime"); 129d50436bbSclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, 130d50436bbSclaudio NULL, 0); 131d50436bbSclaudio break; 132ab0c2486Smichele case SHOW_NBR: 1336fb6d103Srenato printf("%-4s %-15s %-11s %-15s %8s\n", 1346fb6d103Srenato "AF", "ID", "State", "Remote Address", "Uptime"); 13502ff519fSmichele imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 136ab0c2486Smichele break; 137ab0c2486Smichele case SHOW_LIB: 1386fb6d103Srenato printf("%-4s %-20s %-15s %-11s %-13s %6s\n", "AF", 1396fb6d103Srenato "Destination", "Nexthop", "Local Label", "Remote Label", 1406fb6d103Srenato "In Use"); 14102ff519fSmichele imsg_compose(ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0); 142ab0c2486Smichele break; 14392dd8dc8Sclaudio case SHOW_FIB: 1446fb6d103Srenato if (!ldp_addrisset(res->family, &res->addr)) 14502ff519fSmichele imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 146ab0c2486Smichele &res->flags, sizeof(res->flags)); 1476fb6d103Srenato else { 1486fb6d103Srenato memset(&kr, 0, sizeof(kr)); 1496fb6d103Srenato kr.af = res->family; 1506fb6d103Srenato kr.prefix = res->addr; 15102ff519fSmichele imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 1526fb6d103Srenato &kr, sizeof(kr)); 1536fb6d103Srenato } 15492dd8dc8Sclaudio show_fib_head(); 155ab0c2486Smichele break; 15692dd8dc8Sclaudio case SHOW_FIB_IFACE: 157ab0c2486Smichele if (*res->ifname) 15802ff519fSmichele imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, 159ab0c2486Smichele res->ifname, sizeof(res->ifname)); 160ab0c2486Smichele else 16102ff519fSmichele imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); 162ab0c2486Smichele show_interface_head(); 163ab0c2486Smichele break; 164a94c7fd0Srenato case SHOW_L2VPN_PW: 165a94c7fd0Srenato printf("%-11s %-15s %-14s %-10s\n", 166a94c7fd0Srenato "Interface", "Neighbor", "PWID", "Status"); 167a94c7fd0Srenato imsg_compose(ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0); 168a94c7fd0Srenato break; 169a94c7fd0Srenato case SHOW_L2VPN_BINDING: 170a94c7fd0Srenato imsg_compose(ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, 171a94c7fd0Srenato NULL, 0); 172a94c7fd0Srenato break; 1733f117ed9Srenato case CLEAR_NBR: 1743f117ed9Srenato memset(&nbr, 0, sizeof(nbr)); 1753f117ed9Srenato nbr.af = res->family; 1763f117ed9Srenato memcpy(&nbr.raddr, &res->addr, sizeof(nbr.raddr)); 1773f117ed9Srenato imsg_compose(ibuf, IMSG_CTL_CLEAR_NBR, 0, 0, -1, &nbr, 1783f117ed9Srenato sizeof(nbr)); 1793f117ed9Srenato done = 1; 1803f117ed9Srenato break; 18192dd8dc8Sclaudio case FIB: 18292dd8dc8Sclaudio errx(1, "fib couple|decouple"); 183ab0c2486Smichele break; 18492dd8dc8Sclaudio case FIB_COUPLE: 18592dd8dc8Sclaudio imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); 186ab0c2486Smichele printf("couple request sent.\n"); 187ab0c2486Smichele done = 1; 188ab0c2486Smichele break; 18992dd8dc8Sclaudio case FIB_DECOUPLE: 19092dd8dc8Sclaudio imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); 191ab0c2486Smichele printf("decouple request sent.\n"); 192ab0c2486Smichele done = 1; 193ab0c2486Smichele break; 194c3319070Sclaudio case LOG_VERBOSE: 195c3319070Sclaudio verbose = 1; 196c3319070Sclaudio /* FALLTHROUGH */ 197c3319070Sclaudio case LOG_BRIEF: 198c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 199c3319070Sclaudio &verbose, sizeof(verbose)); 200c3319070Sclaudio printf("logging request sent.\n"); 201c3319070Sclaudio done = 1; 202c3319070Sclaudio break; 203ab0c2486Smichele case RELOAD: 20402ff519fSmichele imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 205ab0c2486Smichele printf("reload request sent.\n"); 206ab0c2486Smichele done = 1; 207ab0c2486Smichele break; 208ab0c2486Smichele } 209ab0c2486Smichele 210dd7efffeSclaudio if (imsgbuf_flush(ibuf) == -1) 211ab0c2486Smichele err(1, "write error"); 212ab0c2486Smichele 213ab0c2486Smichele while (!done) { 214668e5ba9Sclaudio if ((n = imsgbuf_read(ibuf)) == -1) 215ef2e27a1Sclaudio err(1, "read error"); 216ab0c2486Smichele if (n == 0) 217ab0c2486Smichele errx(1, "pipe closed"); 218ab0c2486Smichele 219ab0c2486Smichele while (!done) { 220ab0c2486Smichele if ((n = imsg_get(ibuf, &imsg)) == -1) 221ab0c2486Smichele errx(1, "imsg_get error"); 222ab0c2486Smichele if (n == 0) 223ab0c2486Smichele break; 224ab0c2486Smichele switch (res->action) { 225ab0c2486Smichele case SHOW: 226ab0c2486Smichele case SHOW_IFACE: 2276fb6d103Srenato done = show_interface_msg(&imsg, res); 228ab0c2486Smichele break; 229d50436bbSclaudio case SHOW_DISC: 2306fb6d103Srenato done = show_discovery_msg(&imsg, res); 231d50436bbSclaudio break; 232ab0c2486Smichele case SHOW_NBR: 2336fb6d103Srenato done = show_nbr_msg(&imsg, res); 234ab0c2486Smichele break; 235ab0c2486Smichele case SHOW_LIB: 2366fb6d103Srenato done = show_lib_msg(&imsg, res); 237ab0c2486Smichele break; 23892dd8dc8Sclaudio case SHOW_FIB: 2396fb6d103Srenato done = show_fib_msg(&imsg, res); 240ab0c2486Smichele break; 24192dd8dc8Sclaudio case SHOW_FIB_IFACE: 24292dd8dc8Sclaudio done = show_fib_interface_msg(&imsg); 243ab0c2486Smichele break; 244a94c7fd0Srenato case SHOW_L2VPN_PW: 245a94c7fd0Srenato done = show_l2vpn_pw_msg(&imsg); 246a94c7fd0Srenato break; 247a94c7fd0Srenato case SHOW_L2VPN_BINDING: 248a94c7fd0Srenato done = show_l2vpn_binding_msg(&imsg); 249a94c7fd0Srenato break; 250ab0c2486Smichele case NONE: 2513f117ed9Srenato case CLEAR_NBR: 25292dd8dc8Sclaudio case FIB: 25392dd8dc8Sclaudio case FIB_COUPLE: 25492dd8dc8Sclaudio case FIB_DECOUPLE: 255c3319070Sclaudio case LOG_VERBOSE: 256c3319070Sclaudio case LOG_BRIEF: 257ab0c2486Smichele case RELOAD: 258ab0c2486Smichele break; 259ab0c2486Smichele } 260ab0c2486Smichele imsg_free(&imsg); 261ab0c2486Smichele } 262ab0c2486Smichele } 263ab0c2486Smichele close(ctl_sock); 264ab0c2486Smichele free(ibuf); 265ab0c2486Smichele 266ab0c2486Smichele return (0); 267ab0c2486Smichele } 268ab0c2486Smichele 2690f882be7Sstsp uint64_t 2700f882be7Sstsp get_ifms_type(uint8_t if_type) 271ab0c2486Smichele { 2720f882be7Sstsp switch (if_type) { 273ab0c2486Smichele case IFT_ETHER: 274ab0c2486Smichele return (IFM_ETHER); 275ab0c2486Smichele break; 276ab0c2486Smichele case IFT_FDDI: 277ab0c2486Smichele return (IFM_FDDI); 278ab0c2486Smichele break; 279ab0c2486Smichele case IFT_CARP: 280ab0c2486Smichele return (IFM_CARP); 281ab0c2486Smichele break; 282ab0c2486Smichele default: 283ab0c2486Smichele return (0); 284ab0c2486Smichele break; 285ab0c2486Smichele } 286ab0c2486Smichele } 287ab0c2486Smichele 288ab0c2486Smichele #define TF_BUFS 8 289ab0c2486Smichele #define TF_LEN 9 290ab0c2486Smichele 291ab0c2486Smichele const char * 292ab0c2486Smichele fmt_timeframe_core(time_t t) 293ab0c2486Smichele { 294ab0c2486Smichele char *buf; 295ab0c2486Smichele static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 296ab0c2486Smichele static int idx = 0; 297ab0c2486Smichele unsigned int sec, min, hrs, day, week; 298ab0c2486Smichele 299ab0c2486Smichele if (t == 0) 300ab0c2486Smichele return ("Stopped"); 301ab0c2486Smichele 302ab0c2486Smichele buf = tfbuf[idx++]; 303ab0c2486Smichele if (idx == TF_BUFS) 304ab0c2486Smichele idx = 0; 305ab0c2486Smichele 306ab0c2486Smichele week = t; 307ab0c2486Smichele 308ab0c2486Smichele sec = week % 60; 309ab0c2486Smichele week /= 60; 310ab0c2486Smichele min = week % 60; 311ab0c2486Smichele week /= 60; 312ab0c2486Smichele hrs = week % 24; 313ab0c2486Smichele week /= 24; 314ab0c2486Smichele day = week % 7; 315ab0c2486Smichele week /= 7; 316ab0c2486Smichele 317ab0c2486Smichele if (week > 0) 318ab0c2486Smichele snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); 319ab0c2486Smichele else if (day > 0) 320ab0c2486Smichele snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 321ab0c2486Smichele else 322ab0c2486Smichele snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 323ab0c2486Smichele 324ab0c2486Smichele return (buf); 325ab0c2486Smichele } 326ab0c2486Smichele 327ab0c2486Smichele int 3286fb6d103Srenato show_interface_msg(struct imsg *imsg, struct parse_result *res) 329ab0c2486Smichele { 330ab0c2486Smichele struct ctl_iface *iface; 331905cf379Sclaudio char *timers; 332ab0c2486Smichele 333ab0c2486Smichele switch (imsg->hdr.type) { 334ab0c2486Smichele case IMSG_CTL_SHOW_INTERFACE: 335ab0c2486Smichele iface = imsg->data; 336ab0c2486Smichele 3376fb6d103Srenato if (res->family != AF_UNSPEC && res->family != iface->af) 3386fb6d103Srenato break; 3396fb6d103Srenato 340905cf379Sclaudio if (asprintf(&timers, "%u/%u", iface->hello_interval, 341905cf379Sclaudio iface->hello_holdtime) == -1) 342ab0c2486Smichele err(1, NULL); 343905cf379Sclaudio 3446fb6d103Srenato printf("%-4s %-11s %-6s %-10s %-8s %-12s %3u\n", 3456fb6d103Srenato af_name(iface->af), iface->name, 3466fb6d103Srenato if_state_name(iface->state), get_linkstate(iface->if_type, 3476fb6d103Srenato iface->linkstate), iface->uptime == 0 ? "00:00:00" : 3486fb6d103Srenato fmt_timeframe_core(iface->uptime), timers, iface->adj_cnt); 349905cf379Sclaudio free(timers); 350ab0c2486Smichele break; 351ab0c2486Smichele case IMSG_CTL_END: 352ab0c2486Smichele printf("\n"); 353ab0c2486Smichele return (1); 354ab0c2486Smichele default: 355ab0c2486Smichele break; 356ab0c2486Smichele } 357ab0c2486Smichele 358ab0c2486Smichele return (0); 359ab0c2486Smichele } 360ab0c2486Smichele 361ab0c2486Smichele int 3626fb6d103Srenato show_discovery_msg(struct imsg *imsg, struct parse_result *res) 363d50436bbSclaudio { 364d50436bbSclaudio struct ctl_adj *adj; 3656fb6d103Srenato const char *addr; 366d50436bbSclaudio 367d50436bbSclaudio switch (imsg->hdr.type) { 368d50436bbSclaudio case IMSG_CTL_SHOW_DISCOVERY: 369d50436bbSclaudio adj = imsg->data; 370d50436bbSclaudio 3716fb6d103Srenato if (res->family != AF_UNSPEC && res->family != adj->af) 3726fb6d103Srenato break; 3736fb6d103Srenato 3746fb6d103Srenato printf("%-4s %-15s ", af_name(adj->af), inet_ntoa(adj->id)); 375d50436bbSclaudio switch(adj->type) { 376d50436bbSclaudio case HELLO_LINK: 3776fb6d103Srenato printf("%-8s %-15s ", "Link", adj->ifname); 378d50436bbSclaudio break; 379d50436bbSclaudio case HELLO_TARGETED: 3806fb6d103Srenato addr = log_addr(adj->af, &adj->src_addr); 3816fb6d103Srenato 3826fb6d103Srenato printf("%-8s %-15s ", "Targeted", addr); 3836fb6d103Srenato if (strlen(addr) > 15) 3846fb6d103Srenato printf("\n%46s", " "); 385d50436bbSclaudio break; 386d50436bbSclaudio } 3876fb6d103Srenato printf("%9u\n", adj->holdtime); 388d50436bbSclaudio break; 389d50436bbSclaudio case IMSG_CTL_END: 390d50436bbSclaudio printf("\n"); 391d50436bbSclaudio return (1); 392d50436bbSclaudio default: 393d50436bbSclaudio break; 394d50436bbSclaudio } 395d50436bbSclaudio 396d50436bbSclaudio return (0); 397d50436bbSclaudio } 398d50436bbSclaudio 399d50436bbSclaudio int 4006fb6d103Srenato show_lib_msg(struct imsg *imsg, struct parse_result *res) 401ab0c2486Smichele { 402ab0c2486Smichele struct ctl_rt *rt; 4034dcd314eSrenato char *dstnet; 404ab0c2486Smichele 405ab0c2486Smichele switch (imsg->hdr.type) { 406ab0c2486Smichele case IMSG_CTL_SHOW_LIB: 407ab0c2486Smichele rt = imsg->data; 4086fb6d103Srenato 4096fb6d103Srenato if (res->family != AF_UNSPEC && res->family != rt->af) 4106fb6d103Srenato break; 4116fb6d103Srenato 4126fb6d103Srenato if (asprintf(&dstnet, "%s/%d", log_addr(rt->af, &rt->prefix), 413ab0c2486Smichele rt->prefixlen) == -1) 414ab0c2486Smichele err(1, NULL); 415fe033e8fSmichele 4166fb6d103Srenato printf("%-4s %-20s", af_name(rt->af), dstnet); 4176fb6d103Srenato if (strlen(dstnet) > 20) 4186fb6d103Srenato printf("\n%25s", " "); 4196fb6d103Srenato printf(" %-15s %-11s %-13s %6s\n", inet_ntoa(rt->nexthop), 4204dcd314eSrenato log_label(rt->local_label), log_label(rt->remote_label), 421cbddacefSclaudio rt->in_use ? "yes" : "no"); 4226fb6d103Srenato 423ab0c2486Smichele free(dstnet); 424ab0c2486Smichele break; 425ab0c2486Smichele case IMSG_CTL_END: 426ab0c2486Smichele printf("\n"); 427ab0c2486Smichele return (1); 428ab0c2486Smichele default: 429ab0c2486Smichele break; 430ab0c2486Smichele } 431ab0c2486Smichele 432ab0c2486Smichele return (0); 433ab0c2486Smichele } 434ab0c2486Smichele 435ab0c2486Smichele int 4366fb6d103Srenato show_nbr_msg(struct imsg *imsg, struct parse_result *res) 437ab0c2486Smichele { 438ab0c2486Smichele struct ctl_nbr *nbr; 4396fb6d103Srenato const char *addr; 440ab0c2486Smichele 441ab0c2486Smichele switch (imsg->hdr.type) { 442ab0c2486Smichele case IMSG_CTL_SHOW_NBR: 443ab0c2486Smichele nbr = imsg->data; 4446fb6d103Srenato 4456fb6d103Srenato if (res->family != AF_UNSPEC && res->family != nbr->af) 4466fb6d103Srenato break; 4476fb6d103Srenato 4486fb6d103Srenato addr = log_addr(nbr->af, &nbr->raddr); 4496fb6d103Srenato 4506fb6d103Srenato printf("%-4s %-15s %-11s %-15s", 4516fb6d103Srenato af_name(nbr->af), inet_ntoa(nbr->id), 4526fb6d103Srenato nbr_state_name(nbr->nbr_state), addr); 4536fb6d103Srenato if (strlen(addr) > 15) 4546fb6d103Srenato printf("\n%48s", " "); 4556fb6d103Srenato printf(" %8s\n", nbr->uptime == 0 ? "-" : 4566fb6d103Srenato fmt_timeframe_core(nbr->uptime)); 457ab0c2486Smichele break; 458ab0c2486Smichele case IMSG_CTL_END: 459ab0c2486Smichele printf("\n"); 460ab0c2486Smichele return (1); 461ab0c2486Smichele default: 462ab0c2486Smichele break; 463ab0c2486Smichele } 464ab0c2486Smichele 465ab0c2486Smichele return (0); 466ab0c2486Smichele } 467ab0c2486Smichele 468ab0c2486Smichele void 46992dd8dc8Sclaudio show_fib_head(void) 470ab0c2486Smichele { 47186bd313bSclaudio printf("Flags: C = Connected, S = Static\n"); 47286bd313bSclaudio printf(" %-4s %-20s %-17s %-17s %s\n", "Prio", "Destination", 47386bd313bSclaudio "Nexthop", "Local Label", "Remote Label"); 474ab0c2486Smichele } 475ab0c2486Smichele 476ab0c2486Smichele int 4776fb6d103Srenato show_fib_msg(struct imsg *imsg, struct parse_result *res) 478ab0c2486Smichele { 479ab0c2486Smichele struct kroute *k; 480ab0c2486Smichele char *p; 4816fb6d103Srenato const char *nexthop; 482ab0c2486Smichele 483ab0c2486Smichele switch (imsg->hdr.type) { 484ab0c2486Smichele case IMSG_CTL_KROUTE: 485ab0c2486Smichele if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 486ab0c2486Smichele errx(1, "wrong imsg len"); 487ab0c2486Smichele k = imsg->data; 488ab0c2486Smichele 4896fb6d103Srenato if (res->family != AF_UNSPEC && res->family != k->af) 4906fb6d103Srenato break; 4916fb6d103Srenato 49286bd313bSclaudio if (k->flags & F_CONNECTED) 493ab0c2486Smichele printf("C"); 494ab0c2486Smichele else if (k->flags & F_STATIC) 495ab0c2486Smichele printf("S"); 496ab0c2486Smichele else 497ab0c2486Smichele printf(" "); 498ab0c2486Smichele 49986bd313bSclaudio printf(" %3d ", k->priority); 5006fb6d103Srenato if (asprintf(&p, "%s/%u", log_addr(k->af, &k->prefix), 501ab0c2486Smichele k->prefixlen) == -1) 502ab0c2486Smichele err(1, NULL); 503ab0c2486Smichele printf("%-20s ", p); 5046fb6d103Srenato if (strlen(p) > 20) 5056fb6d103Srenato printf("\n%27s", " "); 506ab0c2486Smichele free(p); 507ab0c2486Smichele 5086fb6d103Srenato if (ldp_addrisset(k->af, &k->nexthop)) { 5096fb6d103Srenato switch (k->af) { 5106fb6d103Srenato case AF_INET: 5116fb6d103Srenato printf("%-18s", inet_ntoa(k->nexthop.v4)); 5126fb6d103Srenato break; 5136fb6d103Srenato case AF_INET6: 5146fb6d103Srenato nexthop = log_in6addr_scope(&k->nexthop.v6, 5156fb6d103Srenato k->ifindex); 5166fb6d103Srenato printf("%-18s", nexthop); 5176fb6d103Srenato if (strlen(nexthop) > 18) 5186fb6d103Srenato printf("\n%45s", " "); 5196fb6d103Srenato break; 5206fb6d103Srenato default: 5216fb6d103Srenato printf("%-18s", " "); 5226fb6d103Srenato break; 5236fb6d103Srenato } 5246fb6d103Srenato } else if (k->flags & F_CONNECTED) 525ab0c2486Smichele printf("link#%-13u", k->ifindex); 526ab0c2486Smichele 5274dcd314eSrenato printf("%-18s", log_label(k->local_label)); 5284dcd314eSrenato printf("%s", log_label(k->remote_label)); 529ab0c2486Smichele printf("\n"); 530ab0c2486Smichele break; 531ab0c2486Smichele case IMSG_CTL_END: 532ab0c2486Smichele printf("\n"); 533ab0c2486Smichele return (1); 534ab0c2486Smichele default: 535ab0c2486Smichele break; 536ab0c2486Smichele } 537ab0c2486Smichele 538ab0c2486Smichele return (0); 539ab0c2486Smichele } 540ab0c2486Smichele 541ab0c2486Smichele void 542ab0c2486Smichele show_interface_head(void) 543ab0c2486Smichele { 544ab0c2486Smichele printf("%-15s%-15s%s\n", "Interface", "Flags", 545ab0c2486Smichele "Link state"); 546ab0c2486Smichele } 547ab0c2486Smichele 548ab0c2486Smichele int 54992dd8dc8Sclaudio show_fib_interface_msg(struct imsg *imsg) 550ab0c2486Smichele { 551ab0c2486Smichele struct kif *k; 5520f882be7Sstsp uint64_t ifms_type; 553ab0c2486Smichele 554ab0c2486Smichele switch (imsg->hdr.type) { 555ab0c2486Smichele case IMSG_CTL_IFINFO: 556ab0c2486Smichele k = imsg->data; 557ab0c2486Smichele printf("%-15s", k->ifname); 558ab0c2486Smichele printf("%-15s", k->flags & IFF_UP ? "UP" : ""); 5590f882be7Sstsp ifms_type = get_ifms_type(k->if_type); 560ab0c2486Smichele if (ifms_type) 5610f617141Sclaudio printf("%s, ", get_media_descr(ifms_type)); 5620f617141Sclaudio 5630f882be7Sstsp printf("%s", get_linkstate(k->if_type, k->link_state)); 564ab0c2486Smichele 565ab0c2486Smichele if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { 566ab0c2486Smichele printf(", "); 567ab0c2486Smichele print_baudrate(k->baudrate); 568ab0c2486Smichele } 569ab0c2486Smichele printf("\n"); 570ab0c2486Smichele break; 571ab0c2486Smichele case IMSG_CTL_END: 572ab0c2486Smichele printf("\n"); 573ab0c2486Smichele return (1); 574ab0c2486Smichele default: 575ab0c2486Smichele break; 576ab0c2486Smichele } 577ab0c2486Smichele 578ab0c2486Smichele return (0); 579ab0c2486Smichele } 580ab0c2486Smichele 581a94c7fd0Srenato int 582a94c7fd0Srenato show_l2vpn_pw_msg(struct imsg *imsg) 583a94c7fd0Srenato { 584a94c7fd0Srenato struct ctl_pw *pw; 585a94c7fd0Srenato 586a94c7fd0Srenato switch (imsg->hdr.type) { 587a94c7fd0Srenato case IMSG_CTL_SHOW_L2VPN_PW: 588a94c7fd0Srenato pw = imsg->data; 589a94c7fd0Srenato 590a94c7fd0Srenato printf("%-11s %-15s %-14u %-10s\n", pw->ifname, 59157e0fe15Srenato inet_ntoa(pw->lsr_id), pw->pwid, 592a94c7fd0Srenato (pw->status ? "UP" : "DOWN")); 593a94c7fd0Srenato break; 594a94c7fd0Srenato case IMSG_CTL_END: 595a94c7fd0Srenato printf("\n"); 596a94c7fd0Srenato return (1); 597a94c7fd0Srenato default: 598a94c7fd0Srenato break; 599a94c7fd0Srenato } 600a94c7fd0Srenato 601a94c7fd0Srenato return (0); 602a94c7fd0Srenato } 603a94c7fd0Srenato 604a94c7fd0Srenato int 605a94c7fd0Srenato show_l2vpn_binding_msg(struct imsg *imsg) 606a94c7fd0Srenato { 607a94c7fd0Srenato struct ctl_pw *pw; 608a94c7fd0Srenato 609a94c7fd0Srenato switch (imsg->hdr.type) { 610a94c7fd0Srenato case IMSG_CTL_SHOW_L2VPN_BINDING: 611a94c7fd0Srenato pw = imsg->data; 612a94c7fd0Srenato 613a94c7fd0Srenato printf("Neighbor: %s - PWID: %u (%s)\n", 61457e0fe15Srenato inet_ntoa(pw->lsr_id), pw->pwid, 6154dcd314eSrenato pw_type_name(pw->type)); 616a94c7fd0Srenato printf("%-12s%-15s%-15s%-10s\n", "", "Label", "Group-ID", 617a94c7fd0Srenato "MTU"); 618a94c7fd0Srenato if (pw->local_label != NO_LABEL) 619a94c7fd0Srenato printf(" %-10s%-15u%-15u%u\n", "Local", 620a94c7fd0Srenato pw->local_label, pw->local_gid, pw->local_ifmtu); 621a94c7fd0Srenato else 622a94c7fd0Srenato printf(" %-10s%-15s%-15s%s\n", "Local", "-", 623a94c7fd0Srenato "-", "-"); 624a94c7fd0Srenato if (pw->remote_label != NO_LABEL) 625a94c7fd0Srenato printf(" %-10s%-15u%-15u%u\n", "Remote", 626a94c7fd0Srenato pw->remote_label, pw->remote_gid, 627a94c7fd0Srenato pw->remote_ifmtu); 628a94c7fd0Srenato else 629a94c7fd0Srenato printf(" %-10s%-15s%-15s%s\n", "Remote", "-", 630a94c7fd0Srenato "-", "-"); 631a94c7fd0Srenato break; 632a94c7fd0Srenato case IMSG_CTL_END: 633a94c7fd0Srenato printf("\n"); 634a94c7fd0Srenato return (1); 635a94c7fd0Srenato default: 636a94c7fd0Srenato break; 637a94c7fd0Srenato } 638a94c7fd0Srenato 639a94c7fd0Srenato return (0); 640a94c7fd0Srenato } 641a94c7fd0Srenato 6420f617141Sclaudio const struct if_status_description 6430f617141Sclaudio if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; 644ab0c2486Smichele const struct ifmedia_description 645ab0c2486Smichele ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 646ab0c2486Smichele 647ab0c2486Smichele const char * 648e5605ae3Sderaadt get_media_descr(uint64_t media_type) 649ab0c2486Smichele { 650ab0c2486Smichele const struct ifmedia_description *p; 651ab0c2486Smichele 652ab0c2486Smichele for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 653ab0c2486Smichele if (media_type == p->ifmt_word) 654ab0c2486Smichele return (p->ifmt_string); 655ab0c2486Smichele 656ab0c2486Smichele return ("unknown"); 657ab0c2486Smichele } 658ab0c2486Smichele 659ab0c2486Smichele const char * 6600f882be7Sstsp get_linkstate(uint8_t if_type, int link_state) 661ab0c2486Smichele { 6620f617141Sclaudio const struct if_status_description *p; 6630f617141Sclaudio static char buf[8]; 664ab0c2486Smichele 6650f617141Sclaudio for (p = if_status_descriptions; p->ifs_string != NULL; p++) { 6660f882be7Sstsp if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) 6670f617141Sclaudio return (p->ifs_string); 668ab0c2486Smichele } 6690f617141Sclaudio snprintf(buf, sizeof(buf), "[#%d]", link_state); 6700f617141Sclaudio return (buf); 671ab0c2486Smichele } 672ab0c2486Smichele 673ab0c2486Smichele void 6746c1e7e28Srenato print_baudrate(uint64_t baudrate) 675ab0c2486Smichele { 676ab0c2486Smichele if (baudrate > IF_Gbps(1)) 677ab0c2486Smichele printf("%llu GBit/s", baudrate / IF_Gbps(1)); 678ab0c2486Smichele else if (baudrate > IF_Mbps(1)) 679ab0c2486Smichele printf("%llu MBit/s", baudrate / IF_Mbps(1)); 680ab0c2486Smichele else if (baudrate > IF_Kbps(1)) 681ab0c2486Smichele printf("%llu KBit/s", baudrate / IF_Kbps(1)); 682ab0c2486Smichele else 683ab0c2486Smichele printf("%llu Bit/s", baudrate); 684ab0c2486Smichele } 685