summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_prefix.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_prefix.c')
-rw-r--r--ospf6d/ospf6_prefix.c213
1 files changed, 213 insertions, 0 deletions
diff --git a/ospf6d/ospf6_prefix.c b/ospf6d/ospf6_prefix.c
new file mode 100644
index 00000000..1542200c
--- /dev/null
+++ b/ospf6d/ospf6_prefix.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 1999 Yasuhiro Ohara
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if 0
+
+#include <zebra.h>
+
+#include "log.h"
+#include "prefix.h"
+#include "memory.h"
+#include "linklist.h"
+
+#include "ospf6_prefix.h"
+
+#else /*0*/
+
+#include "ospf6d.h"
+
+#endif /*0*/
+
+struct ospf6_prefix *
+ospf6_prefix_create (u_int8_t options, u_int16_t metric, struct prefix_ipv6 *p)
+{
+ struct prefix_ipv6 prefix;
+ struct ospf6_prefix *o6p;
+ size_t size;
+
+ /* copy prefix and apply mask */
+ prefix_copy ((struct prefix *) &prefix, (struct prefix *) p);
+ apply_mask_ipv6 (&prefix);
+
+ size = OSPF6_PREFIX_SPACE (prefix.prefixlen) + sizeof (struct ospf6_prefix);
+ o6p = (struct ospf6_prefix *) XMALLOC (MTYPE_OSPF6_PREFIX, size);
+ if (! o6p)
+ zlog_warn ("Can't allocate memory for ospf6 prefix: size: %d", size);
+ else
+ memset (o6p, 0, size);
+
+ o6p->prefix_length = prefix.prefixlen;
+ o6p->prefix_options = options;
+ o6p->prefix_metric = htons (metric);
+ memcpy (o6p + 1, &prefix.prefix, OSPF6_PREFIX_SPACE (prefix.prefixlen));
+
+ return o6p;
+}
+
+void
+ospf6_prefix_delete (struct ospf6_prefix *p)
+{
+ XFREE (MTYPE_OSPF6_PREFIX, p);
+}
+
+int
+ospf6_prefix_issame (struct ospf6_prefix *p1, struct ospf6_prefix *p2)
+{
+ if (p1->prefix_length != p2->prefix_length)
+ return 0;
+ if (memcmp (&p1->u, &p2->u, sizeof (p1->u)))
+ return 0;
+ if (memcmp (p1 + 1, p2 + 1, OSPF6_PREFIX_SPACE (p1->prefix_length)))
+ return 0;
+ return 1;
+}
+
+struct ospf6_prefix *
+ospf6_prefix_lookup (list l, struct ospf6_prefix *p1)
+{
+ listnode node;
+ struct ospf6_prefix *p2;
+ for (node = listhead (l); node; nextnode (node))
+ {
+ p2 = (struct ospf6_prefix *) getdata (node);
+ if (ospf6_prefix_issame (p1, p2))
+ return p2;
+ }
+ return NULL;
+}
+
+/* add a copy of given prefix to the list */
+void
+ospf6_prefix_add (list l, struct ospf6_prefix *p)
+{
+ struct ospf6_prefix *add;
+ add = (struct ospf6_prefix *) XMALLOC (MTYPE_OSPF6_PREFIX,
+ OSPF6_PREFIX_SIZE (p));
+ if (add == NULL)
+ {
+ zlog_warn ("Can't allocate memory for ospf6 prefix");
+ return;
+ }
+ else
+ memcpy (add, p, OSPF6_PREFIX_SIZE (p));
+
+ if (ospf6_prefix_lookup (l, add))
+ {
+ ospf6_prefix_delete (add);
+ return;
+ }
+ listnode_add (l, add);
+}
+
+void
+ospf6_prefix_remove (list l, struct ospf6_prefix *p)
+{
+ struct ospf6_prefix *rem;
+ rem = ospf6_prefix_lookup (l, p);
+ if (rem)
+ {
+ listnode_delete (l, rem);
+ ospf6_prefix_delete (rem);
+ }
+}
+
+void
+ospf6_prefix_in6_addr (struct ospf6_prefix *o6p, struct in6_addr *in6)
+{
+ memset (in6, 0, sizeof (struct in6_addr));
+ memcpy (in6, o6p + 1, OSPF6_PREFIX_SPACE (o6p->prefix_length));
+ return;
+}
+
+char *
+ospf6_prefix_options_str (u_int8_t opt, char *buf, size_t bufsize)
+{
+ char *p, *mc, *la, *nu;
+
+ p = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_P) ? "P" : "-");
+ mc = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_MC) ? "MC" : "--");
+ la = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_LA) ? "LA" : "--");
+ nu = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_NU) ? "NU" : "--");
+
+ snprintf (buf, bufsize, "%s|%s|%s|%s", p, mc, la, nu);
+ return buf;
+}
+
+char *
+ospf6_prefix_string (struct ospf6_prefix *prefix, char *buf, size_t size)
+{
+ struct in6_addr in6;
+ char s[64];
+
+ memset (&in6, 0, sizeof (in6));
+ memcpy (&in6, prefix + 1, OSPF6_PREFIX_SPACE (prefix->prefix_length));
+ inet_ntop (AF_INET6, &in6, s, sizeof (s));
+
+ snprintf (buf, size, "%s/%d", s, prefix->prefix_length);
+ return buf;
+}
+
+void
+ospf6_prefix_copy (struct ospf6_prefix *dst, struct ospf6_prefix *src,
+ size_t dstsize)
+{
+ size_t srcsize;
+
+ memset (dst, 0, dstsize);
+
+ srcsize = OSPF6_PREFIX_SIZE (src);
+ if (dstsize < srcsize)
+ memcpy (dst, src, dstsize);
+ else
+ memcpy (dst, src, srcsize);
+
+ return;
+}
+
+void
+ospf6_prefix_apply_mask (struct ospf6_prefix *o6p)
+{
+ u_char *pnt, mask;
+ int index, offset;
+
+ char buf[128];
+ struct in6_addr in6;
+ ospf6_prefix_in6_addr (o6p, &in6);
+ inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
+
+ pnt = (u_char *)(o6p + 1);
+ index = o6p->prefix_length / 8;
+ offset = o6p->prefix_length % 8;
+ mask = 0xff << (8 - offset);
+
+ if (index >= 16)
+ return;
+
+ pnt[index] &= mask;
+ index ++;
+
+ while (index < OSPF6_PREFIX_SPACE (o6p->prefix_length))
+ pnt[index++] = 0;
+
+ ospf6_prefix_in6_addr (o6p, &in6);
+ inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
+}
+