Externalise the output aspect of ospfctl.
It is the first step towards implementing json output support. Diff by Richard Chivers <r.chivers () zengenti . com>, based on Claudio's work. Thanks ! OK claudio@
This commit is contained in:
parent
6a7860a40a
commit
87862bd30e
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
|
@ -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
|
||||
};
|
Loading…
Reference in New Issue