int show_db_msg_detail(struct imsg *imsg) { static struct in_addr area_id; static char ifname[IF_NAMESIZE]; static u_int16_t lasttype; struct in6_addr ia6; struct in_addr addr, data; struct area *area; struct iface *iface; struct lsa *lsa; struct lsa_rtr_link *rtr_link; struct lsa_net_link *net_link; struct lsa_prefix *prefix; struct lsa_asext *asext; u_int32_t ext_tag; 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); asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); printf(" Flags: %s\n", print_asext_flags(ntohl(lsa->data.asext.metric))); printf(" Metric: %d Type: ", ntohl(asext->metric) & LSA_METRIC_MASK); if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) printf("2\n"); else printf("1\n"); prefix = &asext->prefix; bzero(&ia6, sizeof(ia6)); bcopy(prefix + 1, &ia6, LSA_PREFIXSIZE(prefix->prefixlen)); printf(" Prefix: %s/%d%s\n", log_in6addr(&ia6), prefix->prefixlen, print_prefix_opt(prefix->options)); off = sizeof(*asext) + LSA_PREFIXSIZE(prefix->prefixlen); if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_F_FLAG) { bcopy((char *)asext + off, &ia6, sizeof(ia6)); printf(" Forwarding Address: %s\n", log_in6addr(&ia6)); off += sizeof(ia6); } if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_T_FLAG) { bcopy((char *)asext + off, &ext_tag, sizeof(ext_tag)); printf(" External Route Tag: %d\n", ntohl(ext_tag)); } printf("\n"); lasttype = lsa->hdr.type; break; case IMSG_CTL_SHOW_DB_LINK: 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("Options: %s\n", print_ospf_options(LSA_24_GETLO( ntohl(lsa->data.link.opts)))); printf("Link Local Address: %s\n", log_in6addr(&lsa->data.link.lladdr)); nlinks = ntohl(lsa->data.link.numprefix); printf("Number of Prefixes: %d\n", nlinks); off = sizeof(lsa->hdr) + sizeof(struct lsa_link); for (i = 0; i < nlinks; i++) { prefix = (struct lsa_prefix *)((char *)lsa + off); bzero(&ia6, sizeof(ia6)); bcopy(prefix + 1, &ia6, LSA_PREFIXSIZE(prefix->prefixlen)); printf(" Prefix: %s/%d%s\n", log_in6addr(&ia6), prefix->prefixlen, print_prefix_opt(prefix->options)); off += sizeof(struct lsa_prefix) + LSA_PREFIXSIZE(prefix->prefixlen); } printf("\n"); 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); printf("Options: %s\n", print_ospf_options(LSA_24_GETLO(ntohl(lsa->data.net.opts)))); nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) - sizeof(struct lsa_net)) / sizeof(struct lsa_net_link); net_link = (struct lsa_net_link *)((char *)lsa + sizeof(lsa->hdr) + sizeof(lsa->data.net)); printf("Number of Routers: %d\n", nlinks); for (i = 0; i < nlinks; i++) { addr.s_addr = net_link->att_rtr; printf(" Attached Router: %s\n", inet_ntoa(addr)); net_link++; } 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_24_GETHI(ntohl(lsa->data.rtr.opts)))); printf("Options: %s\n", print_ospf_options(LSA_24_GETLO(ntohl(lsa->data.rtr.opts)))); nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) - sizeof(u_int32_t)) / sizeof(struct lsa_rtr_link); 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 (Interface ID %s) connected to: %s\n", log_id(rtr_link->iface_id), print_rtr_link_type(rtr_link->type)); addr.s_addr = rtr_link->nbr_rtr_id; data.s_addr = rtr_link->nbr_iface_id; switch (rtr_link->type) { case LINK_TYPE_POINTTOPOINT: case LINK_TYPE_VIRTUAL: printf(" Router ID: %s\n", inet_ntoa(addr)); printf(" Interface ID: %s\n", inet_ntoa(data)); break; case LINK_TYPE_TRANSIT_NET: printf(" Designated Router ID: %s\n", inet_ntoa(addr)); printf(" DR Interface ID: %s\n", inet_ntoa(data)); break; default: printf(" Link ID (Unknown type %d): %s\n", rtr_link->type, 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); } lasttype = lsa->hdr.type; break; case IMSG_CTL_SHOW_DB_INTRA: 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("Referenced LS Type: %s\n", print_ls_type(lsa->data.pref_intra.ref_type)); addr.s_addr = lsa->data.pref_intra.ref_ls_id; printf("Referenced Link State ID: %s\n", inet_ntoa(addr)); addr.s_addr = lsa->data.pref_intra.ref_adv_rtr; printf("Referenced Advertising Router: %s\n", inet_ntoa(addr)); nlinks = ntohs(lsa->data.pref_intra.numprefix); printf("Number of Prefixes: %d\n", nlinks); off = sizeof(lsa->hdr) + sizeof(struct lsa_intra_prefix); for (i = 0; i < nlinks; i++) { prefix = (struct lsa_prefix *)((char *)lsa + off); bzero(&ia6, sizeof(ia6)); bcopy(prefix + 1, &ia6, LSA_PREFIXSIZE(prefix->prefixlen)); printf(" Prefix: %s/%d%s\n", log_in6addr(&ia6), prefix->prefixlen, print_prefix_opt(prefix->options)); off += sizeof(struct lsa_prefix) + LSA_PREFIXSIZE(prefix->prefixlen); } printf("\n"); lasttype = lsa->hdr.type; break; case IMSG_CTL_SHOW_DB_SUM: 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("Prefix: XXX\n"); printf("Metric: %d\n", ntohl(lsa->data.pref_sum.metric) & LSA_METRIC_MASK); lasttype = lsa->hdr.type; break; 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.rtr_sum.dest_rtr_id; printf("Destination Router ID: %s\n", inet_ntoa(addr)); printf("Options: %s\n", print_ospf_options(ntohl(lsa->data.rtr_sum.opts))); printf("Metric: %d\n\n", ntohl(lsa->data.rtr_sum.metric) & LSA_METRIC_MASK); 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_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); }