\f
/* Display functions */
+static char *
+ospf6_inter_area_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
+ int buflen, int pos)
+{
+ struct ospf6_inter_prefix_lsa *prefix_lsa;
+ struct in6_addr in6;
+
+ if (lsa != NULL)
+ {
+ prefix_lsa = (struct ospf6_inter_prefix_lsa *)
+ OSPF6_LSA_HEADER_END (lsa->header);
+
+ ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
+ if (buf)
+ {
+ inet_ntop (AF_INET6, &in6, buf, buflen);
+ sprintf (&buf[strlen(buf)], "/%d", prefix_lsa->prefix.prefix_length);
+ }
+ }
+
+ return (buf);
+}
+
static int
ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
struct ospf6_inter_prefix_lsa *prefix_lsa;
- struct in6_addr in6;
- char buf[64];
+ char buf[INET6_ADDRSTRLEN];
prefix_lsa = (struct ospf6_inter_prefix_lsa *)
OSPF6_LSA_HEADER_END (lsa->header);
buf, sizeof (buf));
vty_out (vty, " Prefix Options: %s%s", buf, VNL);
- ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
- inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
- vty_out (vty, " Prefix: %s/%d%s", buf,
- prefix_lsa->prefix.prefix_length, VNL);
+ vty_out (vty, " Prefix: %s%s",
+ ospf6_inter_area_prefix_lsa_get_prefix_str (lsa, buf, sizeof(buf),
+ 0), VNL);
return 0;
}
+static char *
+ospf6_inter_area_router_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
+ int buflen, int pos)
+{
+ struct ospf6_inter_router_lsa *router_lsa;
+
+ if (lsa != NULL)
+ {
+ router_lsa = (struct ospf6_inter_router_lsa *)
+ OSPF6_LSA_HEADER_END (lsa->header);
+
+
+ if (buf)
+ inet_ntop (AF_INET, &router_lsa->router_id, buf, buflen);
+ }
+
+ return (buf);
+}
+
static int
ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
vty_out (vty, " Options: %s%s", buf, VNL);
vty_out (vty, " Metric: %lu%s",
(u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa), VNL);
+
inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
vty_out (vty, " Destination Router ID: %s%s", buf, VNL);
{
OSPF6_LSTYPE_INTER_PREFIX,
"Inter-Prefix",
- ospf6_inter_area_prefix_lsa_show
+ "IAP",
+ ospf6_inter_area_prefix_lsa_show,
+ ospf6_inter_area_prefix_lsa_get_prefix_str,
};
struct ospf6_lsa_handler inter_router_handler =
{
OSPF6_LSTYPE_INTER_ROUTER,
"Inter-Router",
- ospf6_inter_area_router_lsa_show
+ "IAR",
+ ospf6_inter_area_router_lsa_show,
+ ospf6_inter_area_router_lsa_get_prefix_str,
};
void
\f
/* Display functions */
+static char *
+ospf6_as_external_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
+ int buflen, int pos)
+{
+ struct ospf6_as_external_lsa *external;
+ struct in6_addr in6;
+ int prefix_length = 0;
+
+ if (lsa)
+ {
+ external = (struct ospf6_as_external_lsa *)
+ OSPF6_LSA_HEADER_END (lsa->header);
+
+ if (pos == 0)
+ {
+ ospf6_prefix_in6_addr (&in6, &external->prefix);
+ prefix_length = external->prefix.prefix_length;
+ }
+ else {
+ in6 = *((struct in6_addr *)
+ ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
+ OSPF6_PREFIX_SPACE (external->prefix.prefix_length)));
+ }
+ if (buf)
+ {
+ inet_ntop (AF_INET6, &in6, buf, buflen);
+ if (prefix_length)
+ sprintf (&buf[strlen(buf)], "/%d", prefix_length);
+ }
+ }
+ return (buf);
+}
+
static int
ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
struct ospf6_as_external_lsa *external;
char buf[64];
- struct in6_addr in6, *forwarding;
assert (lsa->header);
external = (struct ospf6_as_external_lsa *)
ntohs (external->prefix.prefix_refer_lstype),
VNL);
- ospf6_prefix_in6_addr (&in6, &external->prefix);
- inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
- vty_out (vty, " Prefix: %s/%d%s", buf,
- external->prefix.prefix_length, VNL);
+ vty_out (vty, " Prefix: %s%s",
+ ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 0), VNL);
/* Forwarding-Address */
if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
{
- forwarding = (struct in6_addr *)
- ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
- OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
- inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
- vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
+ vty_out (vty, " Forwarding-Address: %s%s",
+ ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 1),
+ VNL);
}
return 0;
{
OSPF6_LSTYPE_AS_EXTERNAL,
"AS-External",
- ospf6_as_external_lsa_show
+ "ASE",
+ ospf6_as_external_lsa_show,
+ ospf6_as_external_lsa_get_prefix_str
};
void
/* RFC2740 3.4.3.1 Router-LSA */
/******************************/
+static char *
+ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen,
+ int pos)
+{
+ struct ospf6_router_lsa *router_lsa;
+ struct ospf6_router_lsdesc *lsdesc;
+ char *start, *end;
+ char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
+
+ if (lsa)
+ {
+ router_lsa = (struct ospf6_router_lsa *)
+ ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
+ start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
+ end = (char *) lsa->header + ntohs (lsa->header->length);
+
+ lsdesc = (struct ospf6_router_lsdesc *)
+ (start + pos*(sizeof (struct ospf6_router_lsdesc)));
+ if ((char *)lsdesc < end)
+ {
+ if (buf && (buflen > INET_ADDRSTRLEN*2))
+ {
+ inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
+ buf1, sizeof(buf1));
+ inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
+ buf2, sizeof(buf2));
+ sprintf (buf, "%s/%s", buf2, buf1);
+ }
+ }
+ else
+ return NULL;
+ }
+
+ return buf;
+}
+
static int
ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
/* RFC2740 3.4.3.2 Network-LSA */
/*******************************/
+static char *
+ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen,
+ int pos)
+{
+ char *start, *end, *current;
+ struct ospf6_network_lsa *network_lsa;
+ struct ospf6_network_lsdesc *lsdesc;
+
+ if (lsa)
+ {
+ network_lsa = (struct ospf6_network_lsa *)
+ ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
+
+ start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
+ end = (char *) lsa->header + ntohs (lsa->header->length);
+ current = start + pos*(sizeof (struct ospf6_network_lsdesc));
+
+ if ((current + sizeof(struct ospf6_network_lsdesc)) <= end)
+ {
+ lsdesc = (struct ospf6_network_lsdesc *)current;
+ if (buf)
+ inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen);
+ }
+ else
+ return NULL;
+ }
+
+ return (buf);
+}
+
static int
ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
/* RFC2740 3.4.3.6 Link-LSA */
/****************************/
+static char *
+ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen,
+ int pos)
+{
+ char *start, *end, *current;
+ struct ospf6_link_lsa *link_lsa;
+ struct in6_addr in6;
+ struct ospf6_prefix *prefix;
+ int cnt = 0, prefixnum;
+
+ if (lsa)
+ {
+ link_lsa = (struct ospf6_link_lsa *)
+ ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
+
+ if (pos == 0) {
+ inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
+ return (buf);
+ }
+
+ prefixnum = ntohl (link_lsa->prefix_num);
+ if (pos > prefixnum)
+ return (NULL);
+
+ start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
+ end = (char *) lsa->header + ntohs (lsa->header->length);
+ current = start;
+
+ do
+ {
+ prefix = (struct ospf6_prefix *) current;
+ if (prefix->prefix_length == 0 ||
+ current + OSPF6_PREFIX_SIZE (prefix) > end)
+ {
+ return (NULL);
+ }
+
+ if (cnt < pos)
+ {
+ current = start + pos*OSPF6_PREFIX_SIZE(prefix);
+ cnt++;
+ }
+ else
+ {
+ memset (&in6, 0, sizeof (in6));
+ memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
+ OSPF6_PREFIX_SPACE (prefix->prefix_length));
+ inet_ntop (AF_INET6, &in6, buf, buflen);
+ return (buf);
+ }
+ } while (current <= end);
+ }
+ return (NULL);
+}
+
static int
ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
/*****************************************/
/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
/*****************************************/
+static char *
+ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
+ int buflen, int pos)
+{
+ char *start, *end, *current;
+ struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
+ struct in6_addr in6;
+ int prefixnum, cnt = 0;
+ struct ospf6_prefix *prefix;
+
+ if (lsa)
+ {
+ intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
+ ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
+
+ prefixnum = ntohs (intra_prefix_lsa->prefix_num);
+ if (pos > prefixnum)
+ return (NULL);
+
+ start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
+ end = (char *) lsa->header + ntohs (lsa->header->length);
+ current = start;
+
+ do
+ {
+ prefix = (struct ospf6_prefix *) current;
+ if (prefix->prefix_length == 0 ||
+ current + OSPF6_PREFIX_SIZE (prefix) > end)
+ {
+ return NULL;
+ }
+
+ if (cnt < pos)
+ {
+ current = start + pos*OSPF6_PREFIX_SIZE(prefix);
+ cnt++;
+ }
+ else
+ {
+ memset (&in6, 0, sizeof (in6));
+ memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
+ OSPF6_PREFIX_SPACE (prefix->prefix_length));
+ inet_ntop (AF_INET6, &in6, buf, buflen);
+ sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length);
+ return (buf);
+ }
+ } while (current <= end);
+ }
+ return (buf);
+}
static int
ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
if (end < current + OSPF6_PREFIX_SIZE (op))
break;
+ /* Appendix A.4.1.1 */
+ if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU) ||
+ CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_LA))
+ {
+ if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
+ {
+ ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
+ buf, sizeof (buf));
+ zlog_debug ("%s: Skipping Prefix %s has NU/LA option set",
+ __func__, buf);
+ }
+ continue;
+ }
+
route = ospf6_route_create ();
memset (&route->prefix, 0, sizeof (struct prefix));
{
OSPF6_LSTYPE_ROUTER,
"Router",
- ospf6_router_lsa_show
+ "Rtr",
+ ospf6_router_lsa_show,
+ ospf6_router_lsa_get_nbr_id
};
struct ospf6_lsa_handler network_handler =
{
OSPF6_LSTYPE_NETWORK,
"Network",
- ospf6_network_lsa_show
+ "Net",
+ ospf6_network_lsa_show,
+ ospf6_network_lsa_get_ar_id
};
struct ospf6_lsa_handler link_handler =
{
OSPF6_LSTYPE_LINK,
"Link",
- ospf6_link_lsa_show
+ "Lnk",
+ ospf6_link_lsa_show,
+ ospf6_link_lsa_get_prefix_str
};
struct ospf6_lsa_handler intra_prefix_handler =
{
OSPF6_LSTYPE_INTRA_PREFIX,
"Intra-Prefix",
- ospf6_intra_prefix_lsa_show
+ "INP",
+ ospf6_intra_prefix_lsa_show,
+ ospf6_intra_prefix_lsa_get_prefix_str
};
void
struct ospf6_lsa_handler unknown_handler =
{
OSPF6_LSTYPE_UNKNOWN,
- "unknown",
+ "Unknown",
+ "Unk",
ospf6_unknown_lsa_show,
+ NULL,
OSPF6_LSA_DEBUG,
};
return buf;
}
+const char *
+ospf6_lstype_short_name (u_int16_t type)
+{
+ static char buf[8];
+ struct ospf6_lsa_handler *handler;
+
+ handler = ospf6_get_lsa_handler (type);
+ if (handler && handler != &unknown_handler)
+ return handler->short_name;
+
+ snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
+ return buf;
+}
+
u_char
ospf6_lstype_debug (u_int16_t type)
{
void
ospf6_lsa_show_summary_header (struct vty *vty)
{
- vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
+ vty_out (vty, "%-4s %-15s%-15s%4s %8s %30s%s",
"Type", "LSId", "AdvRouter", "Age", "SeqNum",
- "Cksm", "Len", "Duration", VNL);
+ "Payload", VNL);
}
void
ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
{
char adv_router[16], id[16];
- struct timeval now, res;
- char duration[16];
+ int type;
+ struct ospf6_lsa_handler *handler;
+ char buf[64], tmpbuf[80];
+ int cnt = 0;
assert (lsa);
assert (lsa->header);
inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
sizeof (adv_router));
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
- timersub (&now, &lsa->installed, &res);
- timerstring (&res, duration, sizeof (duration));
-
- vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
- ospf6_lstype_name (lsa->header->type),
- id, adv_router, ospf6_lsa_age_current (lsa),
- (u_long) ntohl (lsa->header->seqnum),
- ntohs (lsa->header->checksum), ntohs (lsa->header->length),
- duration, VNL);
+ type = ntohs(lsa->header->type);
+ handler = ospf6_get_lsa_handler (lsa->header->type);
+ if ((type == OSPF6_LSTYPE_INTER_PREFIX) ||
+ (type == OSPF6_LSTYPE_INTER_ROUTER) ||
+ (type == OSPF6_LSTYPE_AS_EXTERNAL))
+ {
+ vty_out (vty, "%-4s %-15s%-15s%4hu %8lx %30s%s",
+ ospf6_lstype_short_name (lsa->header->type),
+ id, adv_router, ospf6_lsa_age_current (lsa),
+ (u_long) ntohl (lsa->header->seqnum),
+ handler->get_prefix_str(lsa, buf, sizeof(buf), 0), VNL);
+ }
+ else if (type != OSPF6_LSTYPE_UNKNOWN)
+ {
+ sprintf (tmpbuf, "%-4s %-15s%-15s%4hu %8lx",
+ ospf6_lstype_short_name (lsa->header->type),
+ id, adv_router, ospf6_lsa_age_current (lsa),
+ (u_long) ntohl (lsa->header->seqnum));
+
+ while (handler->get_prefix_str(lsa, buf, sizeof(buf), cnt) != NULL)
+ {
+ vty_out (vty, "%s %30s%s", tmpbuf, buf, VNL);
+ cnt++;
+ }
+ }
+ else
+ {
+ vty_out (vty, "%-4s %-15s%-15s%4hu %8lx%s",
+ ospf6_lstype_short_name (lsa->header->type),
+ id, adv_router, ospf6_lsa_age_current (lsa),
+ (u_long) ntohl (lsa->header->seqnum), VNL);
+ }
}
void
{
char adv_router[64], id[64];
struct ospf6_lsa_handler *handler;
+ struct timeval now, res;
+ char duration[16];
assert (lsa && lsa->header);
inet_ntop (AF_INET, &lsa->header->adv_router,
adv_router, sizeof (adv_router));
+ quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ timersub (&now, &lsa->installed, &res);
+ timerstring (&res, duration, sizeof (duration));
+
vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
ospf6_lstype_name (lsa->header->type), VNL);
vty_out (vty, "Link State ID: %s%s", id, VNL);
vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
ntohs (lsa->header->checksum),
ntohs (lsa->header->length), VNL);
+ vty_out (vty, "Duration: %s%s", duration, VNL);
handler = ospf6_get_lsa_handler (lsa->header->type);
if (handler->show == NULL)
{
u_int16_t type; /* host byte order */
const char *name;
+ const char *short_name;
int (*show) (struct vty *, struct ospf6_lsa *);
+ char *(*get_prefix_str) (struct ospf6_lsa *, char *buf, int buflen, int pos);
u_char debug;
};
\f
/* Function Prototypes */
extern const char *ospf6_lstype_name (u_int16_t type);
+extern const char *ospf6_lstype_short_name (u_int16_t type);
extern u_char ospf6_lstype_debug (u_int16_t type);
extern int ospf6_lsa_is_differ (struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2);
extern int ospf6_lsa_is_changed (struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2);