blob: 54b9bc8a2d443533e3d58a835fd0e2d8b02df4f6 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * Prefix related functions.
3 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "prefix.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "memory.h"
29#include "log.h"
30
31/* Maskbit. */
Stephen Hemminger2d362d12009-12-21 12:54:58 +030032static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
paul718e3742002-12-13 20:15:29 +000033 0xf8, 0xfc, 0xfe, 0xff};
Denis Ovsienko89a7fd12011-10-11 15:17:45 +040034static const u_int32_t maskbytes_host[] =
Denis Ovsienkocc6647f2011-10-08 18:15:21 +040035{
36 0x00000000, /* /0 0.0.0.0 */
37 0x80000000, /* /1 128.0.0.0 */
38 0xc0000000, /* /2 192.0.0.0 */
39 0xe0000000, /* /3 224.0.0.0 */
40 0xf0000000, /* /4 240.0.0.0 */
41 0xf8000000, /* /5 248.0.0.0 */
42 0xfc000000, /* /6 252.0.0.0 */
43 0xfe000000, /* /7 254.0.0.0 */
44 0xff000000, /* /8 255.0.0.0 */
45 0xff800000, /* /9 255.128.0.0 */
46 0xffc00000, /* /10 255.192.0.0 */
47 0xffe00000, /* /11 255.224.0.0 */
48 0xfff00000, /* /12 255.240.0.0 */
49 0xfff80000, /* /13 255.248.0.0 */
50 0xfffc0000, /* /14 255.252.0.0 */
51 0xfffe0000, /* /15 255.254.0.0 */
52 0xffff0000, /* /16 255.255.0.0 */
53 0xffff8000, /* /17 255.255.128.0 */
54 0xffffc000, /* /18 255.255.192.0 */
55 0xffffe000, /* /19 255.255.224.0 */
56 0xfffff000, /* /20 255.255.240.0 */
57 0xfffff800, /* /21 255.255.248.0 */
58 0xfffffc00, /* /22 255.255.252.0 */
59 0xfffffe00, /* /23 255.255.254.0 */
60 0xffffff00, /* /24 255.255.255.0 */
61 0xffffff80, /* /25 255.255.255.128 */
62 0xffffffc0, /* /26 255.255.255.192 */
63 0xffffffe0, /* /27 255.255.255.224 */
64 0xfffffff0, /* /28 255.255.255.240 */
65 0xfffffff8, /* /29 255.255.255.248 */
66 0xfffffffc, /* /30 255.255.255.252 */
67 0xfffffffe, /* /31 255.255.255.254 */
68 0xffffffff /* /32 255.255.255.255 */
69};
Denis Ovsienko89a7fd12011-10-11 15:17:45 +040070static const u_int32_t maskbytes_network[] =
71{
72 0x00000000, /* /0 0.0.0.0 */
73 0x00000080, /* /1 128.0.0.0 */
74 0x000000c0, /* /2 192.0.0.0 */
75 0x000000e0, /* /3 224.0.0.0 */
76 0x000000f0, /* /4 240.0.0.0 */
77 0x000000f8, /* /5 248.0.0.0 */
78 0x000000fc, /* /6 252.0.0.0 */
79 0x000000fe, /* /7 254.0.0.0 */
80 0x000000ff, /* /8 255.0.0.0 */
81 0x000080ff, /* /9 255.128.0.0 */
82 0x0000c0ff, /* /10 255.192.0.0 */
83 0x0000e0ff, /* /11 255.224.0.0 */
84 0x0000f0ff, /* /12 255.240.0.0 */
85 0x0000f8ff, /* /13 255.248.0.0 */
86 0x0000fcff, /* /14 255.252.0.0 */
87 0x0000feff, /* /15 255.254.0.0 */
88 0x0000ffff, /* /16 255.255.0.0 */
89 0x0080ffff, /* /17 255.255.128.0 */
90 0x00c0ffff, /* /18 255.255.192.0 */
91 0x00e0ffff, /* /19 255.255.224.0 */
92 0x00f0ffff, /* /20 255.255.240.0 */
93 0x00f8ffff, /* /21 255.255.248.0 */
94 0x00fcffff, /* /22 255.255.252.0 */
95 0x00feffff, /* /23 255.255.254.0 */
96 0x00ffffff, /* /24 255.255.255.0 */
97 0x80ffffff, /* /25 255.255.255.128 */
98 0xc0ffffff, /* /26 255.255.255.192 */
99 0xe0ffffff, /* /27 255.255.255.224 */
100 0xf0ffffff, /* /28 255.255.255.240 */
101 0xf8ffffff, /* /29 255.255.255.248 */
102 0xfcffffff, /* /30 255.255.255.252 */
103 0xfeffffff, /* /31 255.255.255.254 */
104 0xffffffff /* /32 255.255.255.255 */
105};
Denis Ovsienko49ff2742011-10-17 21:11:10 +0400106static const struct in6_addr maskbytes6[] =
107{
108 /* /0 */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
109 /* /1 */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
110 /* /2 */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
111 /* /3 */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
112 /* /4 */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
113 /* /5 */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
114 /* /6 */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
115 /* /7 */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
116 /* /8 */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
117 /* /9 */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
118 /* /10 */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
119 /* /11 */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
120 /* /12 */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
121 /* /13 */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
122 /* /14 */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
123 /* /15 */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
124 /* /16 */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
125 /* /17 */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
126 /* /18 */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
127 /* /19 */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
128 /* /20 */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
129 /* /21 */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
130 /* /22 */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
131 /* /23 */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
132 /* /24 */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
133 /* /25 */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
134 /* /26 */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
135 /* /27 */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
136 /* /28 */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
137 /* /29 */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
138 /* /30 */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
139 /* /31 */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
140 /* /32 */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
141 /* /33 */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
142 /* /34 */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
143 /* /35 */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
144 /* /36 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
145 /* /37 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
146 /* /38 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
147 /* /39 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
148 /* /40 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
149 /* /41 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
150 /* /42 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
151 /* /43 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
152 /* /44 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
153 /* /45 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
154 /* /46 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
155 /* /47 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
156 /* /48 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
157 /* /49 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
158 /* /50 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
159 /* /51 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
160 /* /52 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
161 /* /53 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
162 /* /54 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
163 /* /55 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
164 /* /56 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
165 /* /57 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
166 /* /58 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
167 /* /59 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
168 /* /60 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
169 /* /61 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
170 /* /62 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
171 /* /63 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
172 /* /64 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
173 /* /65 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
174 /* /66 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
175 /* /67 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
176 /* /68 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
177 /* /69 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
178 /* /70 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
179 /* /71 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
180 /* /72 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
181 /* /73 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
182 /* /74 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
183 /* /75 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
184 /* /76 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
185 /* /77 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
186 /* /78 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
187 /* /79 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
188 /* /80 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
189 /* /81 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
190 /* /82 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
191 /* /83 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
192 /* /84 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
193 /* /85 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
194 /* /86 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
195 /* /87 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
196 /* /88 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
197 /* /89 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } },
198 /* /90 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } },
199 /* /91 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } },
200 /* /92 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } },
201 /* /93 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } },
202 /* /94 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } },
203 /* /95 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } },
204 /* /96 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
205 /* /97 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } },
206 /* /98 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } },
207 /* /99 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } },
208 /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } },
209 /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } },
210 /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } },
211 /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } },
212 /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } },
213 /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } },
214 /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } },
215 /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } },
216 /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } },
217 /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } },
218 /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } },
219 /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } },
220 /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
221 /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } },
222 /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } },
223 /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } },
224 /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } },
225 /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } },
226 /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } },
227 /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } },
228 /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } },
229 /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } },
230 /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } },
231 /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } },
232 /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } },
233 /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } },
234 /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } },
235 /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } },
236 /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
237};
paul718e3742002-12-13 20:15:29 +0000238
239/* Number of bits in prefix type. */
240#ifndef PNBBY
241#define PNBBY 8
242#endif /* PNBBY */
243
244#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
245
246/* Address Famiy Identifier to Address Family converter. */
247int
Michael Lambert4c9641b2010-07-22 13:20:55 -0400248afi2family (afi_t afi)
paul718e3742002-12-13 20:15:29 +0000249{
250 if (afi == AFI_IP)
251 return AF_INET;
252#ifdef HAVE_IPV6
253 else if (afi == AFI_IP6)
254 return AF_INET6;
255#endif /* HAVE_IPV6 */
256 return 0;
257}
258
Michael Lambert4c9641b2010-07-22 13:20:55 -0400259afi_t
paul718e3742002-12-13 20:15:29 +0000260family2afi (int family)
261{
262 if (family == AF_INET)
263 return AFI_IP;
264#ifdef HAVE_IPV6
265 else if (family == AF_INET6)
266 return AFI_IP6;
267#endif /* HAVE_IPV6 */
268 return 0;
269}
270
271/* If n includes p prefix then return 1 else return 0. */
272int
hassob04c6992004-10-04 19:10:31 +0000273prefix_match (const struct prefix *n, const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000274{
275 int offset;
276 int shift;
Paul Jakmae9e42172010-01-24 21:41:02 +0000277 const u_char *np, *pp;
paul718e3742002-12-13 20:15:29 +0000278
279 /* If n's prefix is longer than p's one return 0. */
280 if (n->prefixlen > p->prefixlen)
281 return 0;
282
Paul Jakmae9e42172010-01-24 21:41:02 +0000283 /* Set both prefix's head pointer. */
284 np = (const u_char *)&n->u.prefix;
285 pp = (const u_char *)&p->u.prefix;
286
paul718e3742002-12-13 20:15:29 +0000287 offset = n->prefixlen / PNBBY;
288 shift = n->prefixlen % PNBBY;
289
290 if (shift)
291 if (maskbit[shift] & (np[offset] ^ pp[offset]))
292 return 0;
293
294 while (offset--)
295 if (np[offset] != pp[offset])
296 return 0;
297 return 1;
298}
299
300/* Copy prefix from src to dest. */
301void
hassob04c6992004-10-04 19:10:31 +0000302prefix_copy (struct prefix *dest, const struct prefix *src)
paul718e3742002-12-13 20:15:29 +0000303{
304 dest->family = src->family;
305 dest->prefixlen = src->prefixlen;
306
307 if (src->family == AF_INET)
308 dest->u.prefix4 = src->u.prefix4;
309#ifdef HAVE_IPV6
310 else if (src->family == AF_INET6)
311 dest->u.prefix6 = src->u.prefix6;
312#endif /* HAVE_IPV6 */
313 else if (src->family == AF_UNSPEC)
314 {
315 dest->u.lp.id = src->u.lp.id;
316 dest->u.lp.adv_router = src->u.lp.adv_router;
317 }
318 else
319 {
ajsb9e70282004-12-08 17:14:45 +0000320 zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
paul718e3742002-12-13 20:15:29 +0000321 src->family);
322 assert (0);
323 }
324}
325
gdt9d24baa2004-01-13 14:55:40 +0000326/*
327 * Return 1 if the address/netmask contained in the prefix structure
328 * is the same, and else return 0. For this routine, 'same' requires
329 * that not only the prefix length and the network part be the same,
330 * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
331 * the same. Note that this routine has the same return value sense
332 * as '==' (which is different from prefix_cmp).
333 */
paul718e3742002-12-13 20:15:29 +0000334int
hassob04c6992004-10-04 19:10:31 +0000335prefix_same (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000336{
337 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
338 {
339 if (p1->family == AF_INET)
340 if (IPV4_ADDR_SAME (&p1->u.prefix, &p2->u.prefix))
341 return 1;
342#ifdef HAVE_IPV6
343 if (p1->family == AF_INET6 )
344 if (IPV6_ADDR_SAME (&p1->u.prefix, &p2->u.prefix))
345 return 1;
346#endif /* HAVE_IPV6 */
347 }
348 return 0;
349}
350
gdt9d24baa2004-01-13 14:55:40 +0000351/*
352 * Return 0 if the network prefixes represented by the struct prefix
353 * arguments are the same prefix, and 1 otherwise. Network prefixes
354 * are considered the same if the prefix lengths are equal and the
355 * network parts are the same. Host bits (which are considered masked
356 * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
357 * 10.0.0.2/8 are considered equivalent by this routine. Note that
358 * this routine has the same return sense as strcmp (which is different
359 * from prefix_same).
360 */
paul718e3742002-12-13 20:15:29 +0000361int
hassob04c6992004-10-04 19:10:31 +0000362prefix_cmp (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000363{
364 int offset;
365 int shift;
366
367 /* Set both prefix's head pointer. */
paul8cc41982005-05-06 21:25:49 +0000368 const u_char *pp1 = (const u_char *)&p1->u.prefix;
369 const u_char *pp2 = (const u_char *)&p2->u.prefix;
paul718e3742002-12-13 20:15:29 +0000370
371 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
372 return 1;
373
Denis Ovsienkod3962ba2011-10-24 18:45:05 +0400374 offset = p1->prefixlen / PNBBY;
375 shift = p1->prefixlen % PNBBY;
paul718e3742002-12-13 20:15:29 +0000376
377 if (shift)
378 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
379 return 1;
380
381 while (offset--)
382 if (pp1[offset] != pp2[offset])
383 return 1;
384
385 return 0;
386}
387
David Lamparter188506f2010-02-02 20:16:35 +0100388/*
389 * Count the number of common bits in 2 prefixes. The prefix length is
390 * ignored for this function; the whole prefix is compared. If the prefix
391 * address families don't match, return -1; otherwise the return value is
392 * in range 0 ... maximum prefix length for the address family.
393 */
394int
395prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
396{
397 int pos, bit;
398 int length = 0;
399 u_char xor;
400
401 /* Set both prefix's head pointer. */
402 const u_char *pp1 = (const u_char *)&p1->u.prefix;
403 const u_char *pp2 = (const u_char *)&p2->u.prefix;
404
405 if (p1->family == AF_INET)
406 length = IPV4_MAX_BYTELEN;
407#ifdef HAVE_IPV6
408 if (p1->family == AF_INET6)
409 length = IPV6_MAX_BYTELEN;
410#endif
411 if (p1->family != p2->family || !length)
412 return -1;
413
414 for (pos = 0; pos < length; pos++)
415 if (pp1[pos] != pp2[pos])
416 break;
417 if (pos == length)
418 return pos * 8;
419
420 xor = pp1[pos] ^ pp2[pos];
421 for (bit = 0; bit < 8; bit++)
422 if (xor & (1 << (7 - bit)))
423 break;
424
425 return pos * 8 + bit;
426}
427
paul718e3742002-12-13 20:15:29 +0000428/* Return prefix family type string. */
hassob04c6992004-10-04 19:10:31 +0000429const char *
430prefix_family_str (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000431{
432 if (p->family == AF_INET)
433 return "inet";
434#ifdef HAVE_IPV6
435 if (p->family == AF_INET6)
436 return "inet6";
437#endif /* HAVE_IPV6 */
438 return "unspec";
439}
440
441/* Allocate new prefix_ipv4 structure. */
442struct prefix_ipv4 *
443prefix_ipv4_new ()
444{
445 struct prefix_ipv4 *p;
446
ajs7907c6c2005-07-26 19:55:31 +0000447 /* Call prefix_new to allocate a full-size struct prefix to avoid problems
448 where the struct prefix_ipv4 is cast to struct prefix and unallocated
449 bytes were being referenced (e.g. in structure assignments). */
450 p = (struct prefix_ipv4 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000451 p->family = AF_INET;
452 return p;
453}
454
455/* Free prefix_ipv4 structure. */
456void
457prefix_ipv4_free (struct prefix_ipv4 *p)
458{
ajs7907c6c2005-07-26 19:55:31 +0000459 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000460}
461
462/* When string format is invalid return 0. */
463int
hassob04c6992004-10-04 19:10:31 +0000464str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000465{
466 int ret;
467 int plen;
468 char *pnt;
469 char *cp;
470
471 /* Find slash inside string. */
472 pnt = strchr (str, '/');
473
474 /* String doesn't contail slash. */
475 if (pnt == NULL)
476 {
477 /* Convert string to prefix. */
478 ret = inet_aton (str, &p->prefix);
479 if (ret == 0)
480 return 0;
481
482 /* If address doesn't contain slash we assume it host address. */
483 p->family = AF_INET;
484 p->prefixlen = IPV4_MAX_BITLEN;
485
486 return ret;
487 }
488 else
489 {
490 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
491 strncpy (cp, str, pnt - str);
492 *(cp + (pnt - str)) = '\0';
493 ret = inet_aton (cp, &p->prefix);
494 XFREE (MTYPE_TMP, cp);
495
496 /* Get prefix length. */
497 plen = (u_char) atoi (++pnt);
hasso3fb9cd62004-10-19 19:44:43 +0000498 if (plen > IPV4_MAX_PREFIXLEN)
paul718e3742002-12-13 20:15:29 +0000499 return 0;
500
501 p->family = AF_INET;
502 p->prefixlen = plen;
503 }
504
505 return ret;
506}
507
Denis Ovsienko89a7fd12011-10-11 15:17:45 +0400508/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000509void
Denis Ovsienkocc6647f2011-10-08 18:15:21 +0400510masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000511{
Denis Ovsienkod3962ba2011-10-24 18:45:05 +0400512 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
Denis Ovsienko89a7fd12011-10-11 15:17:45 +0400513 netmask->s_addr = maskbytes_network[masklen];
paul718e3742002-12-13 20:15:29 +0000514}
515
516/* Convert IP address's netmask into integer. We assume netmask is
517 sequential one. Argument netmask should be network byte order. */
518u_char
519ip_masklen (struct in_addr netmask)
520{
521 u_char len;
522 u_char *pnt;
523 u_char *end;
524 u_char val;
525
526 len = 0;
527 pnt = (u_char *) &netmask;
528 end = pnt + 4;
529
ajs330009f2005-07-26 14:35:37 +0000530 while ((pnt < end) && (*pnt == 0xff))
paul718e3742002-12-13 20:15:29 +0000531 {
532 len+= 8;
533 pnt++;
534 }
535
536 if (pnt < end)
537 {
538 val = *pnt;
539 while (val)
540 {
541 len++;
542 val <<= 1;
543 }
544 }
545 return len;
546}
547
Denis Ovsienkoed7a62e2011-10-18 18:33:53 +0400548/* Apply mask to IPv4 prefix (network byte order). */
paul718e3742002-12-13 20:15:29 +0000549void
550apply_mask_ipv4 (struct prefix_ipv4 *p)
551{
Denis Ovsienkoed7a62e2011-10-18 18:33:53 +0400552 assert (p->prefixlen >= 0 && p->prefixlen <= IPV4_MAX_BITLEN);
553 p->prefix.s_addr &= maskbytes_network[p->prefixlen];
paul718e3742002-12-13 20:15:29 +0000554}
555
556/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
557int
hassob04c6992004-10-04 19:10:31 +0000558prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000559{
560 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
561}
562
563#ifdef HAVE_IPV6
564
565/* Allocate a new ip version 6 route */
566struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000567prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000568{
569 struct prefix_ipv6 *p;
570
ajs7907c6c2005-07-26 19:55:31 +0000571 /* Allocate a full-size struct prefix to avoid problems with structure
572 size mismatches. */
573 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000574 p->family = AF_INET6;
575 return p;
576}
577
578/* Free prefix for IPv6. */
579void
580prefix_ipv6_free (struct prefix_ipv6 *p)
581{
ajs7907c6c2005-07-26 19:55:31 +0000582 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000583}
584
585/* If given string is valid return pin6 else return NULL */
586int
hassob04c6992004-10-04 19:10:31 +0000587str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000588{
589 char *pnt;
590 char *cp;
591 int ret;
592
593 pnt = strchr (str, '/');
594
595 /* If string doesn't contain `/' treat it as host route. */
596 if (pnt == NULL)
597 {
598 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100599 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000600 return 0;
601 p->prefixlen = IPV6_MAX_BITLEN;
602 }
603 else
604 {
605 int plen;
606
607 cp = XMALLOC (0, (pnt - str) + 1);
608 strncpy (cp, str, pnt - str);
609 *(cp + (pnt - str)) = '\0';
610 ret = inet_pton (AF_INET6, cp, &p->prefix);
611 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100612 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000613 return 0;
614 plen = (u_char) atoi (++pnt);
Denis Ovsienkod3962ba2011-10-24 18:45:05 +0400615 if (plen > IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000616 return 0;
617 p->prefixlen = plen;
618 }
619 p->family = AF_INET6;
620
621 return ret;
622}
623
hassob04c6992004-10-04 19:10:31 +0000624/* Convert struct in6_addr netmask into integer.
625 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000626int
627ip6_masklen (struct in6_addr netmask)
628{
629 int len = 0;
630 unsigned char val;
631 unsigned char *pnt;
632
633 pnt = (unsigned char *) & netmask;
634
Denis Ovsienkod3962ba2011-10-24 18:45:05 +0400635 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000636 {
637 len += 8;
638 pnt++;
639 }
640
Denis Ovsienkod3962ba2011-10-24 18:45:05 +0400641 if (len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000642 {
643 val = *pnt;
644 while (val)
645 {
646 len++;
647 val <<= 1;
648 }
649 }
650 return len;
651}
652
653void
Denis Ovsienko49ff2742011-10-17 21:11:10 +0400654masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000655{
Denis Ovsienkod3962ba2011-10-24 18:45:05 +0400656 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
Denis Ovsienko49ff2742011-10-17 21:11:10 +0400657 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000658}
659
660void
661apply_mask_ipv6 (struct prefix_ipv6 *p)
662{
Denis Ovsienkoc6cb2d92011-10-18 22:02:52 +0400663 assert (p->prefixlen >= 0 && p->prefixlen <= IPV6_MAX_BITLEN);
664 u_int32_t *addr_word = (u_int32_t *) &p->prefix;
665 u_int32_t *mask_word = (u_int32_t *) (maskbytes6 + p->prefixlen);
666 *addr_word++ &= *mask_word++;
667 *addr_word++ &= *mask_word++;
668 *addr_word++ &= *mask_word++;
669 *addr_word &= *mask_word;
paul718e3742002-12-13 20:15:29 +0000670}
671
672void
hassob04c6992004-10-04 19:10:31 +0000673str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000674{
675 int i;
676 unsigned int x;
677
678 /* %x must point to unsinged int */
679 for (i = 0; i < 16; i++)
680 {
681 sscanf (str + (i * 2), "%02x", &x);
682 addr->s6_addr[i] = x & 0xff;
683 }
684}
685#endif /* HAVE_IPV6 */
686
687void
688apply_mask (struct prefix *p)
689{
690 switch (p->family)
691 {
692 case AF_INET:
693 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
694 break;
695#ifdef HAVE_IPV6
696 case AF_INET6:
697 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
698 break;
699#endif /* HAVE_IPV6 */
700 default:
701 break;
702 }
703 return;
704}
705
hassob04c6992004-10-04 19:10:31 +0000706/* Utility function of convert between struct prefix <=> union sockunion.
707 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000708struct prefix *
hassob04c6992004-10-04 19:10:31 +0000709sockunion2prefix (const union sockunion *dest,
710 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000711{
712 if (dest->sa.sa_family == AF_INET)
713 {
714 struct prefix_ipv4 *p;
715
716 p = prefix_ipv4_new ();
717 p->family = AF_INET;
718 p->prefix = dest->sin.sin_addr;
719 p->prefixlen = ip_masklen (mask->sin.sin_addr);
720 return (struct prefix *) p;
721 }
722#ifdef HAVE_IPV6
723 if (dest->sa.sa_family == AF_INET6)
724 {
725 struct prefix_ipv6 *p;
726
727 p = prefix_ipv6_new ();
728 p->family = AF_INET6;
729 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
730 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
731 return (struct prefix *) p;
732 }
733#endif /* HAVE_IPV6 */
734 return NULL;
735}
736
hassob04c6992004-10-04 19:10:31 +0000737/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000738struct prefix *
hassob04c6992004-10-04 19:10:31 +0000739sockunion2hostprefix (const union sockunion *su)
paul718e3742002-12-13 20:15:29 +0000740{
741 if (su->sa.sa_family == AF_INET)
742 {
743 struct prefix_ipv4 *p;
744
745 p = prefix_ipv4_new ();
746 p->family = AF_INET;
747 p->prefix = su->sin.sin_addr;
748 p->prefixlen = IPV4_MAX_BITLEN;
749 return (struct prefix *) p;
750 }
751#ifdef HAVE_IPV6
752 if (su->sa.sa_family == AF_INET6)
753 {
754 struct prefix_ipv6 *p;
755
756 p = prefix_ipv6_new ();
757 p->family = AF_INET6;
758 p->prefixlen = IPV6_MAX_BITLEN;
759 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
760 return (struct prefix *) p;
761 }
762#endif /* HAVE_IPV6 */
763 return NULL;
764}
765
David Lamparter188506f2010-02-02 20:16:35 +0100766void
767prefix2sockunion (const struct prefix *p, union sockunion *su)
768{
769 memset (su, 0, sizeof (*su));
770
771 su->sa.sa_family = p->family;
772 if (p->family == AF_INET)
773 su->sin.sin_addr = p->u.prefix4;
774#ifdef HAVE_IPV6
775 if (p->family == AF_INET6)
776 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
777#endif /* HAVE_IPV6 */
778}
779
paul718e3742002-12-13 20:15:29 +0000780int
hassob04c6992004-10-04 19:10:31 +0000781prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000782{
783 switch (p->family)
784 {
785 case AF_INET:
786 return IPV4_MAX_BYTELEN;
787 break;
788#ifdef HAVE_IPV6
789 case AF_INET6:
790 return IPV6_MAX_BYTELEN;
791 break;
792#endif /* HAVE_IPV6 */
793 }
794 return 0;
795}
796
797/* Generic function for conversion string to struct prefix. */
798int
hassob04c6992004-10-04 19:10:31 +0000799str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000800{
801 int ret;
802
803 /* First we try to convert string to struct prefix_ipv4. */
804 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
805 if (ret)
806 return ret;
807
808#ifdef HAVE_IPV6
809 /* Next we try to convert string to struct prefix_ipv6. */
810 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
811 if (ret)
812 return ret;
813#endif /* HAVE_IPV6 */
814
815 return 0;
816}
817
818int
hassob04c6992004-10-04 19:10:31 +0000819prefix2str (const struct prefix *p, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000820{
821 char buf[BUFSIZ];
822
823 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
824 snprintf (str, size, "%s/%d", buf, p->prefixlen);
825 return 0;
826}
827
828struct prefix *
829prefix_new ()
830{
831 struct prefix *p;
832
833 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
834 return p;
835}
836
837/* Free prefix structure. */
838void
839prefix_free (struct prefix *p)
840{
841 XFREE (MTYPE_PREFIX, p);
842}
843
844/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000845 * character.
846 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000847int
hassob04c6992004-10-04 19:10:31 +0000848all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000849{
850 for (; *str != '\0'; str++)
851 if (!isdigit ((int) *str))
852 return 0;
853 return 1;
854}
855
856/* Utility function to convert ipv4 prefixes to Classful prefixes */
857void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
858{
859
860 u_int32_t destination;
861
862 destination = ntohl (p->prefix.s_addr);
863
hasso3fb9cd62004-10-19 19:44:43 +0000864 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000865 /* do nothing for host routes */
866 else if (IN_CLASSC (destination))
867 {
868 p->prefixlen=24;
869 apply_mask_ipv4(p);
870 }
871 else if (IN_CLASSB(destination))
872 {
873 p->prefixlen=16;
874 apply_mask_ipv4(p);
875 }
876 else
877 {
878 p->prefixlen=8;
879 apply_mask_ipv4(p);
880 }
881}
882
hasso3fb9cd62004-10-19 19:44:43 +0000883in_addr_t
884ipv4_network_addr (in_addr_t hostaddr, int masklen)
885{
886 struct in_addr mask;
887
888 masklen2ip (masklen, &mask);
889 return hostaddr & mask.s_addr;
890}
891
892in_addr_t
893ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
894{
895 struct in_addr mask;
896
897 masklen2ip (masklen, &mask);
898 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
899 /* normal case */
900 (hostaddr | ~mask.s_addr) :
901 /* special case for /31 */
902 (hostaddr ^ ~mask.s_addr);
903}
904
paul718e3742002-12-13 20:15:29 +0000905/* Utility function to convert ipv4 netmask to prefixes
906 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
907 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
908int
hassob04c6992004-10-04 19:10:31 +0000909netmask_str2prefix_str (const char *net_str, const char *mask_str,
910 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000911{
912 struct in_addr network;
913 struct in_addr mask;
914 u_char prefixlen;
915 u_int32_t destination;
916 int ret;
917
918 ret = inet_aton (net_str, &network);
919 if (! ret)
920 return 0;
921
922 if (mask_str)
923 {
924 ret = inet_aton (mask_str, &mask);
925 if (! ret)
926 return 0;
927
928 prefixlen = ip_masklen (mask);
929 }
930 else
931 {
932 destination = ntohl (network.s_addr);
933
934 if (network.s_addr == 0)
935 prefixlen = 0;
936 else if (IN_CLASSC (destination))
937 prefixlen = 24;
938 else if (IN_CLASSB (destination))
939 prefixlen = 16;
940 else if (IN_CLASSA (destination))
941 prefixlen = 8;
942 else
943 return 0;
944 }
945
946 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
947
948 return 1;
949}
950
hasso59209902005-04-05 14:36:49 +0000951#ifdef HAVE_IPV6
952/* Utility function for making IPv6 address string. */
953const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000954inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000955{
956 static char buf[INET6_ADDRSTRLEN];
957
hasso3a2ce6a2005-04-08 01:30:51 +0000958 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000959 return buf;
960}
961#endif /* HAVE_IPV6 */