summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_intra.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_intra.c')
-rw-r--r--ospf6d/ospf6_intra.c201
1 files changed, 197 insertions, 4 deletions
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 025a7710..9c84e657 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -56,6 +56,42 @@ u_int32_t conf_debug_ospf6_brouter_specific_area_id;
/* 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)
{
@@ -334,6 +370,36 @@ ospf6_router_lsa_originate (struct thread *thread)
/* 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)
{
@@ -480,6 +546,61 @@ ospf6_network_lsa_originate (struct thread *thread)
/* 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)
{
@@ -632,6 +753,56 @@ ospf6_link_lsa_originate (struct thread *thread)
/*****************************************/
/* 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)
@@ -1103,6 +1274,20 @@ ospf6_intra_prefix_lsa_add (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));
@@ -1454,28 +1639,36 @@ struct ospf6_lsa_handler router_handler =
{
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