]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_prefix.c
Start of new ospf6d merge from Zebra.
[mirror_frr.git] / ospf6d / ospf6_prefix.c
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
39 struct ospf6_prefix *
40 ospf6_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
65 void
66 ospf6_prefix_delete (struct ospf6_prefix *p)
67 {
68 XFREE (MTYPE_OSPF6_PREFIX, p);
69 }
70
71 int
72 ospf6_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
83 struct ospf6_prefix *
84 ospf6_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 */
98 void
99 ospf6_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
120 void
121 ospf6_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
132 void
133 ospf6_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
140 char *
141 ospf6_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
154 char *
155 ospf6_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
168 void
169 ospf6_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
185 void
186 ospf6_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