diff options
-rw-r--r-- | usr.sbin/ospfctl/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/ospfctl/ospfctl.c | 997 | ||||
-rw-r--r-- | usr.sbin/ospfctl/ospfctl.h | 53 | ||||
-rw-r--r-- | usr.sbin/ospfctl/output.c | 669 |
4 files changed, 832 insertions, 891 deletions
diff --git a/usr.sbin/ospfctl/Makefile b/usr.sbin/ospfctl/Makefile index cfd5e4ccb71..aa47dce8c84 100644 --- a/usr.sbin/ospfctl/Makefile +++ b/usr.sbin/ospfctl/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.5 2016/09/02 14:02:48 benno Exp $ +# $OpenBSD: Makefile,v 1.6 2020/05/18 17:52:18 denis Exp $ .PATH: ${.CURDIR}/../ospfd PROG= ospfctl -SRCS= logmsg.c ospfctl.c parser.c +SRCS= logmsg.c ospfctl.c output.c parser.c CFLAGS+= -Wall CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual diff --git a/usr.sbin/ospfctl/ospfctl.c b/usr.sbin/ospfctl/ospfctl.c index 2d7189793d8..d5bbce9172e 100644 --- a/usr.sbin/ospfctl/ospfctl.c +++ b/usr.sbin/ospfctl/ospfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfctl.c,v 1.66 2019/11/01 18:15:28 florian Exp $ */ +/* $OpenBSD: ospfctl.c,v 1.67 2020/05/18 17:52:18 denis Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -35,42 +35,16 @@ #include "ospf.h" #include "ospfd.h" +#include "ospfctl.h" #include "ospfe.h" #include "parser.h" __dead void usage(void); -int show_summary_msg(struct imsg *); -uint64_t get_ifms_type(uint8_t); -int show_interface_msg(struct imsg *); -int show_interface_detail_msg(struct imsg *); -const char *print_link(int); -const char *fmt_timeframe(time_t t); -const char *fmt_timeframe_core(time_t t); -const char *log_id(u_int32_t ); -const char *log_adv_rtr(u_int32_t); -void show_database_head(struct in_addr, char *, u_int8_t); -int show_database_msg(struct imsg *); -char *print_ls_type(u_int8_t); -void show_db_hdr_msg_detail(struct lsa_hdr *); -char *print_rtr_link_type(u_int8_t); -const char *print_ospf_flags(u_int8_t); -int show_db_msg_detail(struct imsg *imsg); -int show_nbr_msg(struct imsg *); -const char *print_ospf_options(u_int8_t); -int show_nbr_detail_msg(struct imsg *); -int show_rib_msg(struct imsg *); -void show_rib_head(struct in_addr, u_int8_t, u_int8_t); -const char *print_ospf_rtr_flags(u_int8_t); -int show_rib_detail_msg(struct imsg *); -void show_fib_head(void); -int show_fib_msg(struct imsg *); -void show_interface_head(void); -const char * get_media_descr(uint64_t); -const char * get_linkstate(uint8_t, int); -void print_baudrate(u_int64_t); -int show_fib_interface_msg(struct imsg *); + +int show(struct imsg *, struct parse_result *); struct imsgbuf *ibuf; +const struct output *output = &show_output; __dead void usage(void) @@ -145,10 +119,6 @@ main(int argc, char *argv[]) imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); break; case SHOW_IFACE: - printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n", - "Interface", "Address", "State", "HelloTimer", "Linkstate", - "Uptime", "nc", "ac"); - /*FALLTHROUGH*/ case SHOW_IFACE_DTAIL: if (*res->ifname) { ifidx = if_nametoindex(res->ifname); @@ -159,9 +129,6 @@ main(int argc, char *argv[]) &ifidx, sizeof(ifidx)); break; case SHOW_NBR: - printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri", - "State", "DeadTime", "Address", "Iface","Uptime"); - /*FALLTHROUGH*/ case SHOW_NBR_DTAIL: imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); break; @@ -194,9 +161,6 @@ main(int argc, char *argv[]) imsg_compose(ibuf, IMSG_CTL_SHOW_DB_OPAQ, 0, 0, -1, NULL, 0); break; case SHOW_RIB: - printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", - "Nexthop", "Path Type", "Type", "Cost", "Uptime"); - /*FALLTHROUGH*/ case SHOW_RIB_DTAIL: imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); break; @@ -207,7 +171,6 @@ main(int argc, char *argv[]) else imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, &res->addr, sizeof(res->addr)); - show_fib_head(); break; case SHOW_FIB_IFACE: if (*res->ifname) @@ -215,7 +178,6 @@ main(int argc, char *argv[]) res->ifname, sizeof(res->ifname)); else imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); - show_interface_head(); break; case FIB: errx(1, "fib couple|decouple"); @@ -255,72 +217,30 @@ main(int argc, char *argv[]) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) err(1, "write error"); - while (!done) { - if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) - errx(1, "imsg_read error"); - if (n == 0) - errx(1, "pipe closed"); + /* no output for certain commands such as log verbose */ + if(!done){ + output->head(res); while (!done) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - errx(1, "imsg_get error"); + if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) + errx(1, "imsg_read error"); if (n == 0) - break; - switch (res->action) { - case SHOW: - case SHOW_SUM: - done = show_summary_msg(&imsg); - break; - case SHOW_IFACE: - done = show_interface_msg(&imsg); - break; - case SHOW_IFACE_DTAIL: - done = show_interface_detail_msg(&imsg); - break; - case SHOW_NBR: - done = show_nbr_msg(&imsg); - break; - case SHOW_NBR_DTAIL: - done = show_nbr_detail_msg(&imsg); - break; - case SHOW_DB: - case SHOW_DBBYAREA: - case SHOW_DBSELF: - done = show_database_msg(&imsg); - break; - case SHOW_DBEXT: - case SHOW_DBNET: - case SHOW_DBRTR: - case SHOW_DBSUM: - case SHOW_DBASBR: - case SHOW_DBOPAQ: - done = show_db_msg_detail(&imsg); - break; - case SHOW_RIB: - done = show_rib_msg(&imsg); - break; - case SHOW_RIB_DTAIL: - done = show_rib_detail_msg(&imsg); - break; - case SHOW_FIB: - done = show_fib_msg(&imsg); - break; - case SHOW_FIB_IFACE: - done = show_fib_interface_msg(&imsg); - break; - case NONE: - case FIB: - case FIB_COUPLE: - case FIB_DECOUPLE: - case FIB_RELOAD: - case LOG_VERBOSE: - case LOG_BRIEF: - case RELOAD: - break; + errx(1, "pipe closed"); + + while (!done) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + errx(1, "imsg_get error"); + if (n == 0) + break; + + done = show(&imsg, res); + imsg_free(&imsg); } - imsg_free(&imsg); } + + output->tail(); } + close(ctl_sock); free(ibuf); @@ -328,45 +248,93 @@ main(int argc, char *argv[]) } int -show_summary_msg(struct imsg *imsg) +show(struct imsg *imsg, struct parse_result *res) { struct ctl_sum *sum; struct ctl_sum_area *sumarea; + struct ctl_iface *ctliface; + struct ctl_nbr *nbr; + struct ctl_rt *rt; + struct kroute *k; + struct kif *kif; + static struct in_addr area_id; + struct area *area; + static u_int8_t lasttype; + static char ifname[IF_NAMESIZE]; + struct iface *iface; + struct lsa *lsa; + struct lsa_hdr *lsa_hdr; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_SUM: sum = imsg->data; - printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); - printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); - printf("RFC1583 compatibility flag is "); - if (sum->rfc1583compat) - printf("enabled\n"); - else - printf("disabled\n"); - - printf("SPF delay is %d msec(s), hold time between two SPFs " - "is %d msec(s)\n", sum->spf_delay, sum->spf_hold_time); - printf("Number of external LSA(s) %d (Checksum sum 0x%x)\n", - sum->num_ext_lsa, sum->ext_lsa_cksum); - printf("Number of areas attached to this router: %d\n", - sum->num_area); + output->summary(sum); break; case IMSG_CTL_SHOW_SUM_AREA: sumarea = imsg->data; - printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); - printf(" Number of interfaces in this area: %d\n", - sumarea->num_iface); - printf(" Number of fully adjacent neighbors in this " - "area: %d\n", sumarea->num_adj_nbr); - printf(" SPF algorithm executed %d time(s)\n", - sumarea->num_spf_calc); - printf(" Number LSA(s) %d (Checksum sum 0x%x)\n", - sumarea->num_lsa, sumarea->lsa_cksum); + output->summary_area(sumarea); + break; + case IMSG_CTL_SHOW_INTERFACE: + ctliface = imsg->data; + if(res->action == SHOW_IFACE_DTAIL) + output->interface(ctliface, 1); + else + output->interface(ctliface, 0); + break; + case IMSG_CTL_SHOW_NBR: + nbr = imsg->data; + if(res->action == SHOW_NBR_DTAIL) + output->neighbor(nbr, 1); + else + output->neighbor(nbr, 0); + break; + case IMSG_CTL_SHOW_RIB: + rt = imsg->data; + if(res->action == SHOW_RIB_DTAIL) + output->rib(rt, 1); + else + output->rib(rt, 0); + break; + case IMSG_CTL_KROUTE: + if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) + errx(1, "wrong imsg len"); + k = imsg->data; + output->fib(k); + break; + case IMSG_CTL_IFINFO: + kif = imsg->data; + output->fib_interface(kif); + break; + case IMSG_CTL_SHOW_DB_EXT: + case IMSG_CTL_SHOW_DB_NET: + case IMSG_CTL_SHOW_DB_RTR: + case IMSG_CTL_SHOW_DB_SUM: + case IMSG_CTL_SHOW_DB_ASBR: + case IMSG_CTL_SHOW_DB_OPAQ: + lsa = imsg->data; + output->db(lsa, area_id, lasttype, ifname); + lasttype = lsa->hdr.type; + break; + case IMSG_CTL_SHOW_DATABASE: + case IMSG_CTL_SHOW_DB_SELF: + lsa_hdr = imsg->data; + output->db_simple(lsa_hdr, area_id, lasttype, ifname); + lasttype = lsa_hdr->type; + break; + case IMSG_CTL_AREA: + area = imsg->data; + area_id = area->id; + lasttype = 0; + break; + case IMSG_CTL_IFACE: + iface = imsg->data; + strlcpy(ifname, iface->name, sizeof(ifname)); + lasttype = 0; break; case IMSG_CTL_END: - printf("\n"); return (1); default: + warnx("unknown imsg %d received", imsg->hdr.type); break; } @@ -390,118 +358,6 @@ get_ifms_type(uint8_t if_type) } } -int -show_interface_msg(struct imsg *imsg) -{ - struct ctl_iface *iface; - char *netid; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_INTERFACE: - iface = imsg->data; - - if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), - mask2prefixlen(iface->mask.s_addr)) == -1) - err(1, NULL); - printf("%-11s %-18s %-6s %-10s %-10s %s %3d %3d\n", - iface->name, netid, if_state_name(iface->state), - iface->hello_timer.tv_sec < 0 ? "-" : - fmt_timeframe_core(iface->hello_timer.tv_sec), - get_linkstate(iface->if_type, iface->linkstate), - fmt_timeframe_core(iface->uptime), - iface->nbr_cnt, iface->adj_cnt); - free(netid); - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - -int -show_interface_detail_msg(struct imsg *imsg) -{ - struct ctl_iface *iface; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_INTERFACE: - iface = imsg->data; - printf("\n"); - printf("Interface %s, line protocol is %s\n", - iface->name, print_link(iface->flags)); - printf(" Internet address %s/%d, ", - inet_ntoa(iface->addr), - mask2prefixlen(iface->mask.s_addr)); - printf("Area %s\n", inet_ntoa(iface->area)); - printf(" Linkstate %s,", - get_linkstate(iface->if_type, iface->linkstate)); - printf(" mtu %d\n", iface->mtu); - printf(" Router ID %s, network type %s, cost: %d\n", - inet_ntoa(iface->rtr_id), - if_type_name(iface->type), iface->metric); - printf(" Transmit delay is %d sec(s), state %s, priority %d\n", - iface->transmit_delay, if_state_name(iface->state), - iface->priority); - printf(" Designated Router (ID) %s, ", - inet_ntoa(iface->dr_id)); - printf("interface address %s\n", inet_ntoa(iface->dr_addr)); - printf(" Backup Designated Router (ID) %s, ", - inet_ntoa(iface->bdr_id)); - printf("interface address %s\n", inet_ntoa(iface->bdr_addr)); - if (iface->dead_interval == FAST_RTR_DEAD_TIME) { - printf(" Timer intervals configured, " - "hello %d msec, dead %d, wait %d, retransmit %d\n", - iface->fast_hello_interval, iface->dead_interval, - iface->dead_interval, iface->rxmt_interval); - - } else { - printf(" Timer intervals configured, " - "hello %d, dead %d, wait %d, retransmit %d\n", - iface->hello_interval, iface->dead_interval, - iface->dead_interval, iface->rxmt_interval); - } - if (iface->passive) - printf(" Passive interface (No Hellos)\n"); - else if (iface->hello_timer.tv_sec < 0) - printf(" Hello timer not running\n"); - else - printf(" Hello timer due in %s+%ldmsec\n", - fmt_timeframe_core(iface->hello_timer.tv_sec), - iface->hello_timer.tv_usec / 1000); - printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); - printf(" Neighbor count is %d, adjacent neighbor count is " - "%d\n", iface->nbr_cnt, iface->adj_cnt); - if (iface->auth_type > 0) { - switch (iface->auth_type) { - case AUTH_SIMPLE: - printf(" Simple password authentication " - "enabled\n"); - break; - case AUTH_CRYPT: - printf(" Message digest authentication " - "enabled\n"); - printf(" Primary key id is %d\n", - iface->auth_keyid); - break; - default: - break; - } - } - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - const char * print_link(int state) { @@ -515,22 +371,13 @@ print_link(int state) #define TF_LEN 9 const char * -fmt_timeframe(time_t t) -{ - if (t == 0) - return ("Never"); - else - return (fmt_timeframe_core(time(NULL) - t)); -} - -const char * fmt_timeframe_core(time_t t) { - char *buf; - static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ - static int idx = 0; - unsigned int sec, min, hrs, day; - unsigned long long week; + char *buf; + static char tfbuf[TF_BUFS][TF_LEN];/* ring buffer */ + static int idx = 0; + unsigned int sec, min, hrs, day; + unsigned long long week; if (t == 0) return ("00:00:00"); @@ -598,108 +445,6 @@ mask2prefixlen(in_addr_t ina) return (33 - ffs(ntohl(ina))); } -void -show_database_head(struct in_addr aid, char *ifname, u_int8_t type) -{ - char *header, *format; - int cleanup = 0; - - switch (type) { - case LSA_TYPE_ROUTER: - format = "Router Link States"; - break; - case LSA_TYPE_NETWORK: - format = "Net Link States"; - break; - case LSA_TYPE_SUM_NETWORK: - format = "Summary Net Link States"; - break; - case LSA_TYPE_SUM_ROUTER: - format = "Summary Router Link States"; - break; - case LSA_TYPE_EXTERNAL: - format = NULL; - if ((header = strdup("Type-5 AS External Link States")) == NULL) - err(1, NULL); - break; - case LSA_TYPE_LINK_OPAQ: - format = "Type-9 Link Local Opaque Link States"; - break; - case LSA_TYPE_AREA_OPAQ: - format = "Type-10 Area Local Opaque Link States"; - break; - case LSA_TYPE_AS_OPAQ: - format = NULL; - if ((header = strdup("Type-11 AS Wide Opaque Link States")) == - NULL) - err(1, NULL); - break; - default: - if (asprintf(&format, "LSA type %x", ntohs(type)) == -1) - err(1, NULL); - cleanup = 1; - break; - } - if (type == LSA_TYPE_LINK_OPAQ) { - if (asprintf(&header, "%s (Area %s Interface %s)", format, - inet_ntoa(aid), ifname) == -1) - err(1, NULL); - } else if (type != LSA_TYPE_EXTERNAL && type != LSA_TYPE_AS_OPAQ) - if (asprintf(&header, "%s (Area %s)", format, - inet_ntoa(aid)) == -1) - err(1, NULL); - - printf("\n%-15s %s\n\n", "", header); - free(header); - if (cleanup) - free(format); -} - -int -show_database_msg(struct imsg *imsg) -{ - static struct in_addr area_id; - static char ifname[IF_NAMESIZE]; - static u_int8_t lasttype; - struct area *area; - struct iface *iface; - struct lsa_hdr *lsa; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_DATABASE: - case IMSG_CTL_SHOW_DB_SELF: - lsa = imsg->data; - if (lsa->type != lasttype) { - show_database_head(area_id, ifname, lsa->type); - printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", - "Adv Router", "Age", "Seq#", "Checksum"); - } - printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", - log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), - ntohs(lsa->age), ntohl(lsa->seq_num), - ntohs(lsa->ls_chksum)); - lasttype = lsa->type; - break; - case IMSG_CTL_AREA: - area = imsg->data; - area_id = area->id; - lasttype = 0; - break; - case IMSG_CTL_IFACE: - iface = imsg->data; - strlcpy(ifname, iface->name, sizeof(ifname)); - lasttype = 0; - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - char * print_ls_type(u_int8_t type) { @@ -725,47 +470,6 @@ print_ls_type(u_int8_t type) } } -void -show_db_hdr_msg_detail(struct lsa_hdr *lsa) -{ - printf("LS age: %d\n", ntohs(lsa->age)); - printf("Options: %s\n", print_ospf_options(lsa->opts)); - printf("LS Type: %s\n", print_ls_type(lsa->type)); - - switch (lsa->type) { - case LSA_TYPE_ROUTER: - printf("Link State ID: %s\n", log_id(lsa->ls_id)); - break; - case LSA_TYPE_NETWORK: - printf("Link State ID: %s (address of Designated Router)\n", - log_id(lsa->ls_id)); - break; - case LSA_TYPE_SUM_NETWORK: - printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); - break; - case LSA_TYPE_SUM_ROUTER: - printf("Link State ID: %s (ASBR Router ID)\n", - log_id(lsa->ls_id)); - break; - case LSA_TYPE_EXTERNAL: - printf("Link State ID: %s (External Network Number)\n", - log_id(lsa->ls_id)); - break; - case LSA_TYPE_LINK_OPAQ: - case LSA_TYPE_AREA_OPAQ: - case LSA_TYPE_AS_OPAQ: - printf("Link State ID: %s Type %d ID %d\n", log_id(lsa->ls_id), - LSA_24_GETHI(ntohl(lsa->ls_id)), - LSA_24_GETLO(ntohl(lsa->ls_id))); - break; - } - - printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); - printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); - printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); - printf("Length: %d\n", ntohs(lsa->len)); -} - char * print_rtr_link_type(u_int8_t type) { @@ -795,190 +499,6 @@ print_ospf_flags(u_int8_t opts) return (optbuf); } -int -show_db_msg_detail(struct imsg *imsg) -{ - static struct in_addr area_id; - static char ifname[IF_NAMESIZE]; - static u_int8_t lasttype; - struct in_addr addr, data; - struct area *area; - struct iface *iface; - struct lsa *lsa; - struct lsa_rtr_link *rtr_link; - struct lsa_asext *asext; - u_int16_t i, nlinks, off; - - /* XXX sanity checks! */ - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_DB_EXT: - lsa = imsg->data; - if (lsa->hdr.type != lasttype) - show_database_head(area_id, ifname, lsa->hdr.type); - show_db_hdr_msg_detail(&lsa->hdr); - addr.s_addr = lsa->data.asext.mask; - printf("Network Mask: %s\n", inet_ntoa(addr)); - - asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); - - printf(" Metric type: "); - if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) - printf("2\n"); - else - printf("1\n"); - printf(" Metric: %d\n", ntohl(asext->metric) - & LSA_METRIC_MASK); - addr.s_addr = asext->fw_addr; - printf(" Forwarding Address: %s\n", inet_ntoa(addr)); - printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag)); - - lasttype = lsa->hdr.type; - break; - case IMSG_CTL_SHOW_DB_NET: - lsa = imsg->data; - if (lsa->hdr.type != lasttype) - show_database_head(area_id, ifname, lsa->hdr.type); - show_db_hdr_msg_detail(&lsa->hdr); - addr.s_addr = lsa->data.net.mask; - printf("Network Mask: %s\n", inet_ntoa(addr)); - - nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) - - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); - off = sizeof(lsa->hdr) + sizeof(u_int32_t); - printf("Number of Routers: %d\n", nlinks); - - for (i = 0; i < nlinks; i++) { - addr.s_addr = lsa->data.net.att_rtr[i]; - printf(" Attached Router: %s\n", inet_ntoa(addr)); - } - - printf("\n"); - lasttype = lsa->hdr.type; - break; - case IMSG_CTL_SHOW_DB_RTR: - lsa = imsg->data; - if (lsa->hdr.type != lasttype) - show_database_head(area_id, ifname, lsa->hdr.type); - show_db_hdr_msg_detail(&lsa->hdr); - printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags)); - nlinks = ntohs(lsa->data.rtr.nlinks); - printf("Number of Links: %d\n\n", nlinks); - - off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); - - for (i = 0; i < nlinks; i++) { - rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); - - printf(" Link connected to: %s\n", - print_rtr_link_type(rtr_link->type)); - - addr.s_addr = rtr_link->id; - data.s_addr = rtr_link->data; - - switch (rtr_link->type) { - case LINK_TYPE_POINTTOPOINT: - case LINK_TYPE_VIRTUAL: - printf(" Link ID (Neighbors Router ID):" - " %s\n", inet_ntoa(addr)); - printf(" Link Data (Router Interface " - "address): %s\n", inet_ntoa(data)); - break; - case LINK_TYPE_TRANSIT_NET: - printf(" Link ID (Designated Router " - "address): %s\n", inet_ntoa(addr)); - printf(" Link Data (Router Interface " - "address): %s\n", inet_ntoa(data)); - break; - case LINK_TYPE_STUB_NET: - printf(" Link ID (Network ID): %s\n", - inet_ntoa(addr)); - printf(" Link Data (Network Mask): %s\n", - inet_ntoa(data)); - break; - default: - printf(" Link ID (Unknown): %s\n", - inet_ntoa(addr)); - printf(" Link Data (Unknown): %s\n", - inet_ntoa(data)); - break; - } - - printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); - - off += sizeof(struct lsa_rtr_link) + - rtr_link->num_tos * sizeof(u_int32_t); - } - - lasttype = lsa->hdr.type; - break; - case IMSG_CTL_SHOW_DB_SUM: - case IMSG_CTL_SHOW_DB_ASBR: - lsa = imsg->data; - if (lsa->hdr.type != lasttype) - show_database_head(area_id, ifname, lsa->hdr.type); - show_db_hdr_msg_detail(&lsa->hdr); - addr.s_addr = lsa->data.sum.mask; - printf("Network Mask: %s\n", inet_ntoa(addr)); - printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & - LSA_METRIC_MASK); - lasttype = lsa->hdr.type; - break; - case IMSG_CTL_SHOW_DB_OPAQ: - lsa = imsg->data; - if (lsa->hdr.type != lasttype) - show_database_head(area_id, ifname, lsa->hdr.type); - show_db_hdr_msg_detail(&lsa->hdr); - /* XXX should we hexdump the data? */ - lasttype = lsa->hdr.type; - break; - case IMSG_CTL_AREA: - area = imsg->data; - area_id = area->id; - lasttype = 0; - break; - case IMSG_CTL_IFACE: - iface = imsg->data; - strlcpy(ifname, iface->name, sizeof(ifname)); - lasttype = 0; - break; - case IMSG_CTL_END: - return (1); - default: - break; - } - - return (0); -} - -int -show_nbr_msg(struct imsg *imsg) -{ - struct ctl_nbr *nbr; - char *state; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_NBR: - nbr = imsg->data; - if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), - if_state_name(nbr->iface_state)) == -1) - err(1, NULL); - printf("%-15s %-3d %-12s %-9s", inet_ntoa(nbr->id), - nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); - printf("%-15s %-9s %s\n", inet_ntoa(nbr->addr), nbr->name, - nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); - free(state); - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - const char * print_ospf_options(u_int8_t opts) { @@ -996,128 +516,6 @@ print_ospf_options(u_int8_t opts) return (optbuf); } -int -show_nbr_detail_msg(struct imsg *imsg) -{ - struct ctl_nbr *nbr; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_NBR: - nbr = imsg->data; - printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); - printf("interface address %s\n", inet_ntoa(nbr->addr)); - printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), - nbr->name); - printf(" Neighbor priority is %d, " - "State is %s, %d state changes\n", - nbr->priority, nbr_state_name(nbr->nbr_state), - nbr->state_chng_cnt); - printf(" DR is %s, ", inet_ntoa(nbr->dr)); - printf("BDR is %s\n", inet_ntoa(nbr->bdr)); - printf(" Options %s\n", print_ospf_options(nbr->options)); - printf(" Dead timer due in %s\n", - fmt_timeframe_core(nbr->dead_timer)); - printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); - printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); - printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); - printf(" Link State Retransmission List %d\n", - nbr->ls_retrans_lst_cnt); - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - -int -show_rib_msg(struct imsg *imsg) -{ - struct ctl_rt *rt; - char *dstnet; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_RIB: - rt = imsg->data; - switch (rt->d_type) { - case DT_NET: - if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), - rt->prefixlen) == -1) - err(1, NULL); - break; - case DT_RTR: - if (asprintf(&dstnet, "%s", - inet_ntoa(rt->prefix)) == -1) - err(1, NULL); - break; - default: - errx(1, "Invalid route type"); - } - - printf("%-20s %-16s%s %-12s %-9s %-7d %s\n", dstnet, - inet_ntoa(rt->nexthop), rt->connected ? "C" : " ", - path_type_name(rt->p_type), - dst_type_name(rt->d_type), rt->cost, - rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); - free(dstnet); - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - -void -show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) -{ - char *header, *format, *format2; - - switch (p_type) { - case PT_INTRA_AREA: - case PT_INTER_AREA: - switch (d_type) { - case DT_NET: - format = "Network Routing Table"; - format2 = ""; - break; - case DT_RTR: - format = "Router Routing Table"; - format2 = "Type"; - break; - default: - errx(1, "unknown route type"); - } - break; - case PT_TYPE1_EXT: - case PT_TYPE2_EXT: - format = NULL; - format2 = "Cost 2"; - if ((header = strdup("External Routing Table")) == NULL) - err(1, NULL); - break; - default: - errx(1, "unknown route type"); - } - - if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) - if (asprintf(&header, "%s (Area %s)", format, - inet_ntoa(aid)) == -1) - err(1, NULL); - - printf("\n%-18s %s\n", "", header); - free(header); - - printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", - "Nexthop", "Adv Router", "Path type", "Cost", format2); -} - const char * print_ospf_rtr_flags(u_int8_t opts) { @@ -1130,155 +528,6 @@ print_ospf_rtr_flags(u_int8_t opts) return (optbuf); } -int -show_rib_detail_msg(struct imsg *imsg) -{ - static struct in_addr area_id; - struct ctl_rt *rt; - struct area *area; - char *dstnet; - static u_int8_t lasttype; - - switch (imsg->hdr.type) { - case IMSG_CTL_SHOW_RIB: - rt = imsg->data; - - switch (rt->p_type) { - case PT_INTRA_AREA: - case PT_INTER_AREA: - switch (rt->d_type) { - case DT_NET: - if (lasttype != RIB_NET) - show_rib_head(rt->area, rt->d_type, - rt->p_type); - if (asprintf(&dstnet, "%s/%d", - inet_ntoa(rt->prefix), rt->prefixlen) == -1) - err(1, NULL); - lasttype = RIB_NET; - break; - case DT_RTR: - if (lasttype != RIB_RTR) - show_rib_head(rt->area, rt->d_type, - rt->p_type); - if (asprintf(&dstnet, "%s", - inet_ntoa(rt->prefix)) == -1) - err(1, NULL); - lasttype = RIB_RTR; - break; - default: - errx(1, "unknown route type"); - } - printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); - printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), - path_type_name(rt->p_type), rt->cost); - free(dstnet); - - if (rt->d_type == DT_RTR) - printf(" %-7s", - print_ospf_rtr_flags(rt->flags)); - - printf("\n"); - break; - case PT_TYPE1_EXT: - case PT_TYPE2_EXT: - if (lasttype != RIB_EXT) - show_rib_head(rt->area, rt->d_type, rt->p_type); - - if (asprintf(&dstnet, "%s/%d", - inet_ntoa(rt->prefix), rt->prefixlen) == -1) - err(1, NULL); - - printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); - printf("%-15s %-12s %-7d %-7d\n", - inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), - rt->cost, rt->cost2); - free(dstnet); - - lasttype = RIB_EXT; - break; - default: - errx(1, "unknown route type"); - } - break; - case IMSG_CTL_AREA: - area = imsg->data; - area_id = area->id; - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - -void -show_fib_head(void) -{ - printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); - printf("%-6s %-4s %-20s %-17s\n", "Flags", "Prio", "Destination", "Nexthop"); -} - -int -show_fib_msg(struct imsg *imsg) -{ - struct kroute *k; - char *p; - - switch (imsg->hdr.type) { - case IMSG_CTL_KROUTE: - if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) - errx(1, "wrong imsg len"); - k = imsg->data; - - if (k->flags & F_DOWN) - printf(" "); - else - printf("*"); - - if (!(k->flags & F_KERNEL)) - printf("O"); - else if (k->flags & F_CONNECTED) - printf("C"); - else if (k->flags & F_STATIC) - printf("S"); - else - printf(" "); - - printf(" "); - printf("%4d ", k->priority); - if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) == - -1) - err(1, NULL); - printf("%-20s ", p); - free(p); - - if (k->nexthop.s_addr) - printf("%s", inet_ntoa(k->nexthop)); - else if (k->flags & F_CONNECTED) - printf("link#%u", k->ifindex); - printf("\n"); - - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} - -void -show_interface_head(void) -{ - printf("%-15s%-15s%s\n", "Interface", "Flags", - "Link state"); -} - const struct if_status_description if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; const struct ifmedia_description @@ -1310,48 +559,18 @@ get_linkstate(uint8_t if_type, int link_state) return (buf); } -void +const char * print_baudrate(u_int64_t baudrate) { + static char buf[32]; if (baudrate > IF_Gbps(1)) - printf("%llu GBit/s", baudrate / IF_Gbps(1)); + snprintf(buf, sizeof(buf), "%llu GBit/s", baudrate / IF_Gbps(1)); else if (baudrate > IF_Mbps(1)) - printf("%llu MBit/s", baudrate / IF_Mbps(1)); + snprintf(buf, sizeof(buf), "%llu MBit/s", baudrate / IF_Mbps(1)); else if (baudrate > IF_Kbps(1)) - printf("%llu KBit/s", baudrate / IF_Kbps(1)); + snprintf(buf, sizeof(buf), "%llu KBit/s", baudrate / IF_Kbps(1)); else - printf("%llu Bit/s", baudrate); + snprintf(buf, sizeof(buf), "%llu Bit/s", baudrate); + return (buf); } -int -show_fib_interface_msg(struct imsg *imsg) -{ - struct kif *k; - uint64_t ifms_type; - - switch (imsg->hdr.type) { - case IMSG_CTL_IFINFO: - k = imsg->data; - printf("%-15s", k->ifname); - printf("%-15s", k->flags & IFF_UP ? "UP" : ""); - ifms_type = get_ifms_type(k->if_type); - if (ifms_type) - printf("%s, ", get_media_descr(ifms_type)); - - printf("%s", get_linkstate(k->if_type, k->link_state)); - - if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { - printf(", "); - print_baudrate(k->baudrate); - } - printf("\n"); - break; - case IMSG_CTL_END: - printf("\n"); - return (1); - default: - break; - } - - return (0); -} diff --git a/usr.sbin/ospfctl/ospfctl.h b/usr.sbin/ospfctl/ospfctl.h new file mode 100644 index 00000000000..5700e52c777 --- /dev/null +++ b/usr.sbin/ospfctl/ospfctl.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> + * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> + * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct parse_result; + +struct output { + void (*head)(struct parse_result *); + void (*interface)(struct ctl_iface *, int); + void (*summary)(struct ctl_sum *); + void (*summary_area)(struct ctl_sum_area *); + void (*neighbor)(struct ctl_nbr *, int); + void (*rib)(struct ctl_rt *, int); + void (*fib)(struct kroute *); + void (*fib_interface)(struct kif *); + void (*db)(struct lsa *, struct in_addr, u_int8_t, + char ifname[IF_NAMESIZE]); + void (*db_simple)(struct lsa_hdr *, struct in_addr, u_int8_t, + char ifname[IF_NAMESIZE]); + void (*tail)(void); +}; + +extern const struct output show_output, json_output; + +#define EOL0(flag) ((flag & F_CTL_SSV) ? ';' : '\n') + +const char *fmt_timeframe_core(time_t); +const char *get_linkstate(uint8_t, int); +const char *print_ospf_rtr_flags(u_int8_t); +const char *print_ospf_options(u_int8_t); +uint64_t get_ifms_type(uint8_t); +const char *get_media_descr(uint64_t); +const char *print_baudrate(u_int64_t); +const char *print_link(int); +char *print_ls_type(u_int8_t); +const char *log_id(u_int32_t ); +const char *log_adv_rtr(u_int32_t); +const char *print_ospf_flags(u_int8_t); +char *print_rtr_link_type(u_int8_t); diff --git a/usr.sbin/ospfctl/output.c b/usr.sbin/ospfctl/output.c new file mode 100644 index 00000000000..9e4f8cb5efd --- /dev/null +++ b/usr.sbin/ospfctl/output.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> + * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> + * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> + * Copyright (c) 2020 Richard Chivers <r.chivers@zengenti.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "ospf.h" +#include "ospfd.h" +#include "ospfctl.h" +#include "ospfe.h" +#include "parser.h" + +static void +show_head(struct parse_result *res) +{ + switch (res->action) { + case SHOW_IFACE: + printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n", + "Interface", "Address", "State", "HelloTimer", "Linkstate", + "Uptime", "nc", "ac"); + break; + case SHOW_FIB: + printf("flags: * = valid, O = OSPF, C = Connected, " + "S = Static\n"); + printf("%-6s %-4s %-20s %-17s\n", "Flags", "Prio", + "Destination", "Nexthop"); + break; + case SHOW_FIB_IFACE: + printf("%-15s%-15s%s\n", "Interface", "Flags", "Link state"); + break; + case SHOW_NBR: + printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri", + "State", "DeadTime", "Address", "Iface","Uptime"); + break; + case SHOW_RIB: + printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", + "Nexthop", "Path Type", "Type", "Cost", "Uptime"); + break; + default: + break; + } +} + +static void +show_summary(struct ctl_sum *sum) +{ + printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); + printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); + printf("RFC1583 compatibility flag is "); + if (sum->rfc1583compat) + printf("enabled\n"); + else + printf("disabled\n"); + + printf("SPF delay is %d msec(s), hold time between two SPFs " + "is %d msec(s)\n", sum->spf_delay, sum->spf_hold_time); + printf("Number of external LSA(s) %d (Checksum sum 0x%x)\n", + sum->num_ext_lsa, sum->ext_lsa_cksum); + printf("Number of areas attached to this router: %d\n", + sum->num_area); +} + +static void +show_summary_area(struct ctl_sum_area *sumarea){ + printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); + printf(" Number of interfaces in this area: %d\n", + sumarea->num_iface); + printf(" Number of fully adjacent neighbors in this " + "area: %d\n", sumarea->num_adj_nbr); + printf(" SPF algorithm executed %d time(s)\n", + sumarea->num_spf_calc); + printf(" Number LSA(s) %d (Checksum sum 0x%x)\n", + sumarea->num_lsa, sumarea->lsa_cksum); +} + +static void +show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) +{ + char *header, *format, *format2; + + switch (p_type) { + case PT_INTRA_AREA: + case PT_INTER_AREA: + switch (d_type) { + case DT_NET: + format = "Network Routing Table"; + format2 = ""; + break; + case DT_RTR: + format = "Router Routing Table"; + format2 = "Type"; + break; + default: + errx(1, "unknown route type"); + } + break; + case PT_TYPE1_EXT: + case PT_TYPE2_EXT: + format = NULL; + format2 = "Cost 2"; + if ((header = strdup("External Routing Table")) == NULL) + err(1, NULL); + break; + default: + errx(1, "unknown route type"); + } + + if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) + if (asprintf(&header, "%s (Area %s)", format, + inet_ntoa(aid)) == -1) + err(1, NULL); + + printf("\n%-18s %s\n", "", header); + free(header); + + printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", + "Nexthop", "Adv Router", "Path type", "Cost", format2); +} + +static void +show_interface(struct ctl_iface *iface, int detail) +{ + char *netid; + + // This wasn't previously executed on detail call + if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), + mask2prefixlen(iface->mask.s_addr)) == -1) + err(1, NULL); + + if(detail){ + printf("\n"); + printf("Interface %s, line protocol is %s\n", + iface->name, print_link(iface->flags)); + printf(" Internet address %s/%d, ", + inet_ntoa(iface->addr), + mask2prefixlen(iface->mask.s_addr)); + printf("Area %s\n", inet_ntoa(iface->area)); + printf(" Linkstate %s,", + get_linkstate(iface->if_type, iface->linkstate)); + printf(" mtu %d\n", iface->mtu); + printf(" Router ID %s, network type %s, cost: %d\n", + inet_ntoa(iface->rtr_id), + if_type_name(iface->type), iface->metric); + printf(" Transmit delay is %d sec(s), state %s, priority %d\n", + iface->transmit_delay, if_state_name(iface->state), + iface->priority); + printf(" Designated Router (ID) %s, ", inet_ntoa(iface->dr_id)); + printf("interface address %s\n", inet_ntoa(iface->dr_addr)); + printf(" Backup Designated Router (ID) %s, ", + inet_ntoa(iface->bdr_id)); + printf("interface address %s\n", inet_ntoa(iface->bdr_addr)); + if (iface->dead_interval == FAST_RTR_DEAD_TIME) { + printf(" Timer intervals configured, " + "hello %d msec, dead %d, wait %d, retransmit %d\n", + iface->fast_hello_interval, iface->dead_interval, + iface->dead_interval, iface->rxmt_interval); + + } else { + printf(" Timer intervals configured, " + "hello %d, dead %d, wait %d, retransmit %d\n", + iface->hello_interval, iface->dead_interval, + iface->dead_interval, iface->rxmt_interval); + } + + if (iface->passive) + printf(" Passive interface (No Hellos)\n"); + else if (iface->hello_timer.tv_sec < 0) + printf(" Hello timer not running\n"); + else + printf(" Hello timer due in %s+%ldmsec\n", + fmt_timeframe_core(iface->hello_timer.tv_sec), + iface->hello_timer.tv_usec / 1000); + printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); + printf(" Neighbor count is %d, adjacent neighbor count is " + "%d\n", iface->nbr_cnt, iface->adj_cnt); + + if (iface->auth_type > 0) { + switch (iface->auth_type) { + case AUTH_SIMPLE: + printf(" Simple password authentication " + "enabled\n"); + break; + case AUTH_CRYPT: + printf(" Message digest authentication " + "enabled\n"); + printf(" Primary key id is %d\n", + iface->auth_keyid); + break; + default: + break; + } + } + }else{ + printf("%-11s %-18s %-6s %-10s %-10s %s %3d %3d\n", + iface->name, netid, if_state_name(iface->state), + iface->hello_timer.tv_sec < 0 ? "-" : + fmt_timeframe_core(iface->hello_timer.tv_sec), + get_linkstate(iface->if_type, iface->linkstate), + fmt_timeframe_core(iface->uptime), + iface->nbr_cnt, iface->adj_cnt); + } + free(netid); +} + + +static void +show_neighbor(struct ctl_nbr *nbr, int detail) +{ + char *state; + + if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), + if_state_name(nbr->iface_state)) == -1) + err(1, NULL); + + if(detail){ + printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); + printf("interface address %s\n", inet_ntoa(nbr->addr)); + printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), + nbr->name); + printf(" Neighbor priority is %d, " + "State is %s, %d state changes\n", + nbr->priority, nbr_state_name(nbr->nbr_state), + nbr->state_chng_cnt); + printf(" DR is %s, ", inet_ntoa(nbr->dr)); + printf("BDR is %s\n", inet_ntoa(nbr->bdr)); + printf(" Options %s\n", print_ospf_options(nbr->options)); + printf(" Dead timer due in %s\n", + fmt_timeframe_core(nbr->dead_timer)); + printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); + printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); + printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); + printf(" Link State Retransmission List %d\n", + nbr->ls_retrans_lst_cnt); + }else{ + printf("%-15s %-3d %-12s %-9s", inet_ntoa(nbr->id), + nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); + printf("%-15s %-9s %s\n", inet_ntoa(nbr->addr), nbr->name, + nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); + } + free(state); +} + +static void +show_rib(struct ctl_rt *rt, int detail) +{ + char *dstnet; + static u_int8_t lasttype; + + if(detail){ + switch (rt->p_type) { + case PT_INTRA_AREA: + case PT_INTER_AREA: + switch (rt->d_type) { + case DT_NET: + if (lasttype != RIB_NET) + show_rib_head(rt->area, rt->d_type, + rt->p_type); + if (asprintf(&dstnet, "%s/%d", + inet_ntoa(rt->prefix), rt->prefixlen) == -1) + err(1, NULL); + lasttype = RIB_NET; + break; + case DT_RTR: + if (lasttype != RIB_RTR) + show_rib_head(rt->area, rt->d_type, + rt->p_type); + if (asprintf(&dstnet, "%s", + inet_ntoa(rt->prefix)) == -1) + err(1, NULL); + lasttype = RIB_RTR; + break; + default: + errx(1, "unknown route type"); + } + printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); + printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), + path_type_name(rt->p_type), rt->cost); + free(dstnet); + + if (rt->d_type == DT_RTR) + printf(" %-7s", + print_ospf_rtr_flags(rt->flags)); + + printf("\n"); + break; + case PT_TYPE1_EXT: + case PT_TYPE2_EXT: + if (lasttype != RIB_EXT) + show_rib_head(rt->area, rt->d_type, rt->p_type); + + if (asprintf(&dstnet, "%s/%d", + inet_ntoa(rt->prefix), rt->prefixlen) == -1) + err(1, NULL); + + printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); + printf("%-15s %-12s %-7d %-7d\n", + inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), + rt->cost, rt->cost2); + free(dstnet); + + lasttype = RIB_EXT; + break; + default: + errx(1, "unknown route type"); + } + }else{ + switch (rt->d_type) { + case DT_NET: + if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), + rt->prefixlen) == -1) + err(1, NULL); + break; + case DT_RTR: + if (asprintf(&dstnet, "%s", + inet_ntoa(rt->prefix)) == -1) + err(1, NULL); + break; + default: + errx(1, "Invalid route type"); + } + + printf("%-20s %-16s%s %-12s %-9s %-7d %s\n", dstnet, + inet_ntoa(rt->nexthop), rt->connected ? "C" : " ", + path_type_name(rt->p_type), + dst_type_name(rt->d_type), rt->cost, + rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); + free(dstnet); + } +} + +static void +show_fib(struct kroute *k) +{ + char *p; + + if (k->flags & F_DOWN) + printf(" "); + else + printf("*"); + + if (!(k->flags & F_KERNEL)) + printf("O"); + else if (k->flags & F_CONNECTED) + printf("C"); + else if (k->flags & F_STATIC) + printf("S"); + else + printf(" "); + + printf(" "); + printf("%4d ", k->priority); + if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) == + -1) + err(1, NULL); + + printf("%-20s ", p); + free(p); + + if (k->nexthop.s_addr) + printf("%s", inet_ntoa(k->nexthop)); + else if (k->flags & F_CONNECTED) + printf("link#%u", k->ifindex); + + printf("\n"); +} + +static void +show_fib_interface(struct kif *k) +{ + uint64_t ifms_type; + + printf("%-15s", k->ifname); + printf("%-15s", k->flags & IFF_UP ? "UP" : ""); + ifms_type = get_ifms_type(k->if_type); + if (ifms_type) + printf("%s, ", get_media_descr(ifms_type)); + + printf("%s", get_linkstate(k->if_type, k->link_state)); + + if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { + printf(", "); + printf("%s", print_baudrate(k->baudrate)); + } + printf("\n"); +} + +static void +show_database_head(struct in_addr aid, char *ifname, u_int8_t type) +{ + char *header, *format; + int cleanup = 0; + + switch (type) { + case LSA_TYPE_ROUTER: + format = "Router Link States"; + break; + case LSA_TYPE_NETWORK: + format = "Net Link States"; + break; + case LSA_TYPE_SUM_NETWORK: + format = "Summary Net Link States"; + break; + case LSA_TYPE_SUM_ROUTER: + format = "Summary Router Link States"; + break; + case LSA_TYPE_EXTERNAL: + format = NULL; + if ((header = strdup("Type-5 AS External Link States")) == NULL) + err(1, NULL); + break; + case LSA_TYPE_LINK_OPAQ: + format = "Type-9 Link Local Opaque Link States"; + break; + case LSA_TYPE_AREA_OPAQ: + format = "Type-10 Area Local Opaque Link States"; + break; + case LSA_TYPE_AS_OPAQ: + format = NULL; + if ((header = strdup("Type-11 AS Wide Opaque Link States")) == + NULL) + err(1, NULL); + break; + default: + if (asprintf(&format, "LSA type %x", ntohs(type)) == -1) + err(1, NULL); + cleanup = 1; + break; + } + if (type == LSA_TYPE_LINK_OPAQ) { + if (asprintf(&header, "%s (Area %s Interface %s)", format, + inet_ntoa(aid), ifname) == -1) + err(1, NULL); + } else if (type != LSA_TYPE_EXTERNAL && type != LSA_TYPE_AS_OPAQ) + if (asprintf(&header, "%s (Area %s)", format, + inet_ntoa(aid)) == -1) + err(1, NULL); + + printf("\n%-15s %s\n\n", "", header); + free(header); + if (cleanup) + free(format); +} + +static void +show_db_hdr_msg_detail(struct lsa_hdr *lsa) +{ + printf("LS age: %d\n", ntohs(lsa->age)); + printf("Options: %s\n", print_ospf_options(lsa->opts)); + printf("LS Type: %s\n", print_ls_type(lsa->type)); + + switch (lsa->type) { + case LSA_TYPE_ROUTER: + printf("Link State ID: %s\n", log_id(lsa->ls_id)); + break; + case LSA_TYPE_NETWORK: + printf("Link State ID: %s (address of Designated Router)\n", + log_id(lsa->ls_id)); + break; + case LSA_TYPE_SUM_NETWORK: + printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); + break; + case LSA_TYPE_SUM_ROUTER: + printf("Link State ID: %s (ASBR Router ID)\n", + log_id(lsa->ls_id)); + break; + case LSA_TYPE_EXTERNAL: + printf("Link State ID: %s (External Network Number)\n", + log_id(lsa->ls_id)); + break; + case LSA_TYPE_LINK_OPAQ: + case LSA_TYPE_AREA_OPAQ: + case LSA_TYPE_AS_OPAQ: + printf("Link State ID: %s Type %d ID %d\n", log_id(lsa->ls_id), + LSA_24_GETHI(ntohl(lsa->ls_id)), + LSA_24_GETLO(ntohl(lsa->ls_id))); + break; + } + + printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); + printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); + printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); + printf("Length: %d\n", ntohs(lsa->len)); +} + +static void +show_db_simple(struct lsa_hdr *lsa, struct in_addr area_id, u_int8_t lasttype, + char ifname[IF_NAMESIZE]) +{ + if (lsa->type != lasttype) { + show_database_head(area_id, ifname, lsa->type); + printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", + "Adv Router", "Age", "Seq#", "Checksum"); + } + printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", + log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), + ntohs(lsa->age), ntohl(lsa->seq_num), + ntohs(lsa->ls_chksum)); +} +static void +show_db(struct lsa *lsa, struct in_addr area_id, u_int8_t lasttype, + char ifname[IF_NAMESIZE]) +{ + struct in_addr addr, data; + struct lsa_asext *asext; + struct lsa_rtr_link *rtr_link; + u_int16_t i, nlinks, off; + + if (lsa->hdr.type != lasttype) + show_database_head(area_id, ifname, lsa->hdr.type); + show_db_hdr_msg_detail(&lsa->hdr); + + switch (lsa->hdr.type) { + case LSA_TYPE_EXTERNAL: + addr.s_addr = lsa->data.asext.mask; + printf("Network Mask: %s\n", inet_ntoa(addr)); + + asext = (struct lsa_asext *)((char *)lsa + + sizeof(lsa->hdr)); + + printf(" Metric type: "); + if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) + printf("2\n"); + else + printf("1\n"); + printf(" Metric: %d\n", ntohl(asext->metric) + & LSA_METRIC_MASK); + addr.s_addr = asext->fw_addr; + printf(" Forwarding Address: %s\n", inet_ntoa(addr)); + printf(" External Route Tag: %d\n\n", + ntohl(asext->ext_tag)); + break; + case LSA_TYPE_NETWORK: + addr.s_addr = lsa->data.net.mask; + printf("Network Mask: %s\n", inet_ntoa(addr)); + + nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) + - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); + off = sizeof(lsa->hdr) + sizeof(u_int32_t); + printf("Number of Routers: %d\n", nlinks); + + for (i = 0; i < nlinks; i++) { + addr.s_addr = lsa->data.net.att_rtr[i]; + printf(" Attached Router: %s\n", + inet_ntoa(addr)); + } + + printf("\n"); + break; + case LSA_TYPE_ROUTER: + printf("Flags: %s\n", + print_ospf_flags(lsa->data.rtr.flags)); + nlinks = ntohs(lsa->data.rtr.nlinks); + printf("Number of Links: %d\n\n", nlinks); + + off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); + + for (i = 0; i < nlinks; i++) { + rtr_link = + (struct lsa_rtr_link *)((char *)lsa + off); + + printf(" Link connected to: %s\n", + print_rtr_link_type(rtr_link->type)); + + addr.s_addr = rtr_link->id; + data.s_addr = rtr_link->data; + + switch (rtr_link->type) { + case LINK_TYPE_POINTTOPOINT: + case LINK_TYPE_VIRTUAL: + printf(" Link ID (Neighbors Router " + "ID): %s\n", inet_ntoa(addr)); + printf(" Link Data (Router Interface " + "address): %s\n", inet_ntoa(data)); + break; + case LINK_TYPE_TRANSIT_NET: + printf(" Link ID (Designated Router " + "address): %s\n", inet_ntoa(addr)); + printf(" Link Data (Router Interface " + "address): %s\n", inet_ntoa(data)); + break; + case LINK_TYPE_STUB_NET: + printf(" Link ID (Network ID): %s\n", + inet_ntoa(addr)); + printf(" Link Data (Network Mask): " + "%s\n", inet_ntoa(data)); + break; + default: + printf(" Link ID (Unknown): %s\n", + inet_ntoa(addr)); + printf(" Link Data (Unknown): %s\n", + inet_ntoa(data)); + break; + } + + printf(" Metric: %d\n\n", + ntohs(rtr_link->metric)); + + off += sizeof(struct lsa_rtr_link) + + rtr_link->num_tos * sizeof(u_int32_t); + } + break; + case LSA_TYPE_SUM_ROUTER: + if (lsa->hdr.type != lasttype) + show_database_head(area_id, ifname, + lsa->hdr.type); + show_db_hdr_msg_detail(&lsa->hdr); + addr.s_addr = lsa->data.sum.mask; + printf("Network Mask: %s\n", inet_ntoa(addr)); + printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & + LSA_METRIC_MASK); + break; + case LSA_TYPE_LINK_OPAQ: + case LSA_TYPE_AREA_OPAQ: + case LSA_TYPE_AS_OPAQ: + if (lsa->hdr.type != lasttype) + show_database_head(area_id, ifname, + lsa->hdr.type); + show_db_hdr_msg_detail(&lsa->hdr); + break; + } +} + +static void +show_tail(void) +{ + /* nothing */ +} + +const struct output show_output = { + .head = show_head, + .summary = show_summary, + .summary_area = show_summary_area, + .interface = show_interface, + .neighbor = show_neighbor, + .rib = show_rib, + .fib = show_fib, + .fib_interface = show_fib_interface, + .db = show_db, + .db_simple = show_db_simple, + .tail = show_tail +}; |