blob: 1ddbbbe7e8df4dde578202bf23de9466c6e96efd [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
374 offset = p1->prefixlen / 8;
375 shift = p1->prefixlen % 8;
376
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 Ovsienkocc6647f2011-10-08 18:15:21 +0400512 assert (masklen >= 0 && masklen <= 32);
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);
615 if (plen > 128)
616 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
635 while ((*pnt == 0xff) && len < 128)
636 {
637 len += 8;
638 pnt++;
639 }
640
641 if (len < 128)
642 {
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 Ovsienko49ff2742011-10-17 21:11:10 +0400656 assert (masklen >=0 && masklen <= 128);
657 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{
663 u_char *pnt;
664 int index;
665 int offset;
666
667 index = p->prefixlen / 8;
668
669 if (index < 16)
670 {
671 pnt = (u_char *) &p->prefix;
672 offset = p->prefixlen % 8;
673
674 pnt[index] &= maskbit[offset];
675 index++;
676
677 while (index < 16)
678 pnt[index++] = 0;
679 }
680}
681
682void
hassob04c6992004-10-04 19:10:31 +0000683str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000684{
685 int i;
686 unsigned int x;
687
688 /* %x must point to unsinged int */
689 for (i = 0; i < 16; i++)
690 {
691 sscanf (str + (i * 2), "%02x", &x);
692 addr->s6_addr[i] = x & 0xff;
693 }
694}
695#endif /* HAVE_IPV6 */
696
697void
698apply_mask (struct prefix *p)
699{
700 switch (p->family)
701 {
702 case AF_INET:
703 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
704 break;
705#ifdef HAVE_IPV6
706 case AF_INET6:
707 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
708 break;
709#endif /* HAVE_IPV6 */
710 default:
711 break;
712 }
713 return;
714}
715
hassob04c6992004-10-04 19:10:31 +0000716/* Utility function of convert between struct prefix <=> union sockunion.
717 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000718struct prefix *
hassob04c6992004-10-04 19:10:31 +0000719sockunion2prefix (const union sockunion *dest,
720 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000721{
722 if (dest->sa.sa_family == AF_INET)
723 {
724 struct prefix_ipv4 *p;
725
726 p = prefix_ipv4_new ();
727 p->family = AF_INET;
728 p->prefix = dest->sin.sin_addr;
729 p->prefixlen = ip_masklen (mask->sin.sin_addr);
730 return (struct prefix *) p;
731 }
732#ifdef HAVE_IPV6
733 if (dest->sa.sa_family == AF_INET6)
734 {
735 struct prefix_ipv6 *p;
736
737 p = prefix_ipv6_new ();
738 p->family = AF_INET6;
739 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
740 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
741 return (struct prefix *) p;
742 }
743#endif /* HAVE_IPV6 */
744 return NULL;
745}
746
hassob04c6992004-10-04 19:10:31 +0000747/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000748struct prefix *
hassob04c6992004-10-04 19:10:31 +0000749sockunion2hostprefix (const union sockunion *su)
paul718e3742002-12-13 20:15:29 +0000750{
751 if (su->sa.sa_family == AF_INET)
752 {
753 struct prefix_ipv4 *p;
754
755 p = prefix_ipv4_new ();
756 p->family = AF_INET;
757 p->prefix = su->sin.sin_addr;
758 p->prefixlen = IPV4_MAX_BITLEN;
759 return (struct prefix *) p;
760 }
761#ifdef HAVE_IPV6
762 if (su->sa.sa_family == AF_INET6)
763 {
764 struct prefix_ipv6 *p;
765
766 p = prefix_ipv6_new ();
767 p->family = AF_INET6;
768 p->prefixlen = IPV6_MAX_BITLEN;
769 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
770 return (struct prefix *) p;
771 }
772#endif /* HAVE_IPV6 */
773 return NULL;
774}
775
David Lamparter188506f2010-02-02 20:16:35 +0100776void
777prefix2sockunion (const struct prefix *p, union sockunion *su)
778{
779 memset (su, 0, sizeof (*su));
780
781 su->sa.sa_family = p->family;
782 if (p->family == AF_INET)
783 su->sin.sin_addr = p->u.prefix4;
784#ifdef HAVE_IPV6
785 if (p->family == AF_INET6)
786 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
787#endif /* HAVE_IPV6 */
788}
789
paul718e3742002-12-13 20:15:29 +0000790int
hassob04c6992004-10-04 19:10:31 +0000791prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000792{
793 switch (p->family)
794 {
795 case AF_INET:
796 return IPV4_MAX_BYTELEN;
797 break;
798#ifdef HAVE_IPV6
799 case AF_INET6:
800 return IPV6_MAX_BYTELEN;
801 break;
802#endif /* HAVE_IPV6 */
803 }
804 return 0;
805}
806
807/* Generic function for conversion string to struct prefix. */
808int
hassob04c6992004-10-04 19:10:31 +0000809str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000810{
811 int ret;
812
813 /* First we try to convert string to struct prefix_ipv4. */
814 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
815 if (ret)
816 return ret;
817
818#ifdef HAVE_IPV6
819 /* Next we try to convert string to struct prefix_ipv6. */
820 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
821 if (ret)
822 return ret;
823#endif /* HAVE_IPV6 */
824
825 return 0;
826}
827
828int
hassob04c6992004-10-04 19:10:31 +0000829prefix2str (const struct prefix *p, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000830{
831 char buf[BUFSIZ];
832
833 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
834 snprintf (str, size, "%s/%d", buf, p->prefixlen);
835 return 0;
836}
837
838struct prefix *
839prefix_new ()
840{
841 struct prefix *p;
842
843 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
844 return p;
845}
846
847/* Free prefix structure. */
848void
849prefix_free (struct prefix *p)
850{
851 XFREE (MTYPE_PREFIX, p);
852}
853
854/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000855 * character.
856 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000857int
hassob04c6992004-10-04 19:10:31 +0000858all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000859{
860 for (; *str != '\0'; str++)
861 if (!isdigit ((int) *str))
862 return 0;
863 return 1;
864}
865
866/* Utility function to convert ipv4 prefixes to Classful prefixes */
867void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
868{
869
870 u_int32_t destination;
871
872 destination = ntohl (p->prefix.s_addr);
873
hasso3fb9cd62004-10-19 19:44:43 +0000874 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000875 /* do nothing for host routes */
876 else if (IN_CLASSC (destination))
877 {
878 p->prefixlen=24;
879 apply_mask_ipv4(p);
880 }
881 else if (IN_CLASSB(destination))
882 {
883 p->prefixlen=16;
884 apply_mask_ipv4(p);
885 }
886 else
887 {
888 p->prefixlen=8;
889 apply_mask_ipv4(p);
890 }
891}
892
hasso3fb9cd62004-10-19 19:44:43 +0000893in_addr_t
894ipv4_network_addr (in_addr_t hostaddr, int masklen)
895{
896 struct in_addr mask;
897
898 masklen2ip (masklen, &mask);
899 return hostaddr & mask.s_addr;
900}
901
902in_addr_t
903ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
904{
905 struct in_addr mask;
906
907 masklen2ip (masklen, &mask);
908 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
909 /* normal case */
910 (hostaddr | ~mask.s_addr) :
911 /* special case for /31 */
912 (hostaddr ^ ~mask.s_addr);
913}
914
paul718e3742002-12-13 20:15:29 +0000915/* Utility function to convert ipv4 netmask to prefixes
916 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
917 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
918int
hassob04c6992004-10-04 19:10:31 +0000919netmask_str2prefix_str (const char *net_str, const char *mask_str,
920 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000921{
922 struct in_addr network;
923 struct in_addr mask;
924 u_char prefixlen;
925 u_int32_t destination;
926 int ret;
927
928 ret = inet_aton (net_str, &network);
929 if (! ret)
930 return 0;
931
932 if (mask_str)
933 {
934 ret = inet_aton (mask_str, &mask);
935 if (! ret)
936 return 0;
937
938 prefixlen = ip_masklen (mask);
939 }
940 else
941 {
942 destination = ntohl (network.s_addr);
943
944 if (network.s_addr == 0)
945 prefixlen = 0;
946 else if (IN_CLASSC (destination))
947 prefixlen = 24;
948 else if (IN_CLASSB (destination))
949 prefixlen = 16;
950 else if (IN_CLASSA (destination))
951 prefixlen = 8;
952 else
953 return 0;
954 }
955
956 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
957
958 return 1;
959}
960
hasso59209902005-04-05 14:36:49 +0000961#ifdef HAVE_IPV6
962/* Utility function for making IPv6 address string. */
963const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000964inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000965{
966 static char buf[INET6_ADDRSTRLEN];
967
hasso3a2ce6a2005-04-08 01:30:51 +0000968 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000969 return buf;
970}
971#endif /* HAVE_IPV6 */