diff options
author | paul <paul> | 2002-12-13 20:15:29 +0000 |
---|---|---|
committer | paul <paul> | 2002-12-13 20:15:29 +0000 |
commit | 718e3744195351130f4ce7dbe0613f4b3e23df93 (patch) | |
tree | bac2ad39971cd43f31241ef123bd4e470f695ac9 /ospf6d/ospf6_prefix.c |
Initial revision
Diffstat (limited to 'ospf6d/ospf6_prefix.c')
-rw-r--r-- | ospf6d/ospf6_prefix.c | 213 |
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)); +} + |