1/* 2 * Copyright (C) 1999 Yasuhiro Ohara 3 * 4 * This file is part of GNU Zebra. 5 * 6 * GNU Zebra is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2, or (at your option) any 9 * later version. 10 * 11 * GNU Zebra is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with GNU Zebra; see the file COPYING. If not, write to the 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 02111-1307, USA. 20 */ 21 22#if 0 23 24#include <zebra.h> 25 26#include "log.h" 27#include "prefix.h" 28#include "memory.h" 29#include "linklist.h" 30 31#include "ospf6_prefix.h" 32 33#else /*0*/ 34 35#include "ospf6d.h" 36 37#endif /*0*/ 38 39struct ospf6_prefix * 40ospf6_prefix_create (u_int8_t options, u_int16_t metric, struct prefix_ipv6 *p) 41{ 42 struct prefix_ipv6 prefix; 43 struct ospf6_prefix *o6p; 44 size_t size; 45 46 /* copy prefix and apply mask */ 47 prefix_copy ((struct prefix *) &prefix, (struct prefix *) p); 48 apply_mask_ipv6 (&prefix); 49 50 size = OSPF6_PREFIX_SPACE (prefix.prefixlen) + sizeof (struct ospf6_prefix); 51 o6p = (struct ospf6_prefix *) XMALLOC (MTYPE_OSPF6_PREFIX, size); 52 if (! o6p) 53 zlog_warn ("Can't allocate memory for ospf6 prefix: size: %d", size); 54 else 55 memset (o6p, 0, size); 56 57 o6p->prefix_length = prefix.prefixlen; 58 o6p->prefix_options = options; 59 o6p->prefix_metric = htons (metric); 60 memcpy (o6p + 1, &prefix.prefix, OSPF6_PREFIX_SPACE (prefix.prefixlen)); 61 62 return o6p; 63} 64 65void 66ospf6_prefix_delete (struct ospf6_prefix *p) 67{ 68 XFREE (MTYPE_OSPF6_PREFIX, p); 69} 70 71int 72ospf6_prefix_issame (struct ospf6_prefix *p1, struct ospf6_prefix *p2) 73{ 74 if (p1->prefix_length != p2->prefix_length) 75 return 0; 76 if (memcmp (&p1->u, &p2->u, sizeof (p1->u))) 77 return 0; 78 if (memcmp (p1 + 1, p2 + 1, OSPF6_PREFIX_SPACE (p1->prefix_length))) 79 return 0; 80 return 1; 81} 82 83struct ospf6_prefix * 84ospf6_prefix_lookup (list l, struct ospf6_prefix *p1) 85{ 86 listnode node; 87 struct ospf6_prefix *p2; 88 for (node = listhead (l); node; nextnode (node)) 89 { 90 p2 = (struct ospf6_prefix *) getdata (node); 91 if (ospf6_prefix_issame (p1, p2)) 92 return p2; 93 } 94 return NULL; 95} 96 97/* add a copy of given prefix to the list */ 98void 99ospf6_prefix_add (list l, struct ospf6_prefix *p) 100{ 101 struct ospf6_prefix *add; 102 add = (struct ospf6_prefix *) XMALLOC (MTYPE_OSPF6_PREFIX, 103 OSPF6_PREFIX_SIZE (p)); 104 if (add == NULL) 105 { 106 zlog_warn ("Can't allocate memory for ospf6 prefix"); 107 return; 108 } 109 else 110 memcpy (add, p, OSPF6_PREFIX_SIZE (p)); 111 112 if (ospf6_prefix_lookup (l, add)) 113 { 114 ospf6_prefix_delete (add); 115 return; 116 } 117 listnode_add (l, add); 118} 119 120void 121ospf6_prefix_remove (list l, struct ospf6_prefix *p) 122{ 123 struct ospf6_prefix *rem; 124 rem = ospf6_prefix_lookup (l, p); 125 if (rem) 126 { 127 listnode_delete (l, rem); 128 ospf6_prefix_delete (rem); 129 } 130} 131 132void 133ospf6_prefix_in6_addr (struct ospf6_prefix *o6p, struct in6_addr *in6) 134{ 135 memset (in6, 0, sizeof (struct in6_addr)); 136 memcpy (in6, o6p + 1, OSPF6_PREFIX_SPACE (o6p->prefix_length)); 137 return; 138} 139 140char * 141ospf6_prefix_options_str (u_int8_t opt, char *buf, size_t bufsize) 142{ 143 char *p, *mc, *la, *nu; 144 145 p = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_P) ? "P" : "-"); 146 mc = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_MC) ? "MC" : "--"); 147 la = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_LA) ? "LA" : "--"); 148 nu = (CHECK_FLAG (opt, OSPF6_PREFIX_OPTION_NU) ? "NU" : "--"); 149 150 snprintf (buf, bufsize, "%s|%s|%s|%s", p, mc, la, nu); 151 return buf; 152} 153 154char * 155ospf6_prefix_string (struct ospf6_prefix *prefix, char *buf, size_t size) 156{ 157 struct in6_addr in6; 158 char s[64]; 159 160 memset (&in6, 0, sizeof (in6)); 161 memcpy (&in6, prefix + 1, OSPF6_PREFIX_SPACE (prefix->prefix_length)); 162 inet_ntop (AF_INET6, &in6, s, sizeof (s)); 163 164 snprintf (buf, size, "%s/%d", s, prefix->prefix_length); 165 return buf; 166} 167 168void 169ospf6_prefix_copy (struct ospf6_prefix *dst, struct ospf6_prefix *src, 170 size_t dstsize) 171{ 172 size_t srcsize; 173 174 memset (dst, 0, dstsize); 175 176 srcsize = OSPF6_PREFIX_SIZE (src); 177 if (dstsize < srcsize) 178 memcpy (dst, src, dstsize); 179 else 180 memcpy (dst, src, srcsize); 181 182 return; 183} 184 185void 186ospf6_prefix_apply_mask (struct ospf6_prefix *o6p) 187{ 188 u_char *pnt, mask; 189 int index, offset; 190 191 char buf[128]; 192 struct in6_addr in6; 193 ospf6_prefix_in6_addr (o6p, &in6); 194 inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); 195 196 pnt = (u_char *)(o6p + 1); 197 index = o6p->prefix_length / 8; 198 offset = o6p->prefix_length % 8; 199 mask = 0xff << (8 - offset); 200 201 if (index >= 16) 202 return; 203 204 pnt[index] &= mask; 205 index ++; 206 207 while (index < OSPF6_PREFIX_SPACE (o6p->prefix_length)) 208 pnt[index++] = 0; 209 210 ospf6_prefix_in6_addr (o6p, &in6); 211 inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); 212} 213 214