blob: 075c9dabd131c555eea6a0860feb25b259e5ab4a [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 Ovsienko051954f2011-10-11 15:17:45 +040034static const u_int32_t maskbytes_host[] =
Denis Ovsienko96633862011-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 Ovsienko051954f2011-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 Ovsienko21f569e2011-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 Jakmad3583442010-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 Jakmad3583442010-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 Lamparter17e52062010-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 Ovsienko051954f2011-10-11 15:17:45 +0400508/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000509void
Denis Ovsienko96633862011-10-08 18:15:21 +0400510masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000511{
Denis Ovsienko96633862011-10-08 18:15:21 +0400512 assert (masklen >= 0 && masklen <= 32);
Denis Ovsienko051954f2011-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
548/* Apply mask to IPv4 prefix. */
549void
550apply_mask_ipv4 (struct prefix_ipv4 *p)
551{
552 u_char *pnt;
553 int index;
554 int offset;
555
556 index = p->prefixlen / 8;
557
558 if (index < 4)
559 {
560 pnt = (u_char *) &p->prefix;
561 offset = p->prefixlen % 8;
562
563 pnt[index] &= maskbit[offset];
564 index++;
565
566 while (index < 4)
567 pnt[index++] = 0;
568 }
569}
570
571/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
572int
hassob04c6992004-10-04 19:10:31 +0000573prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000574{
575 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
576}
577
578#ifdef HAVE_IPV6
579
580/* Allocate a new ip version 6 route */
581struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000582prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000583{
584 struct prefix_ipv6 *p;
585
ajs7907c6c2005-07-26 19:55:31 +0000586 /* Allocate a full-size struct prefix to avoid problems with structure
587 size mismatches. */
588 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000589 p->family = AF_INET6;
590 return p;
591}
592
593/* Free prefix for IPv6. */
594void
595prefix_ipv6_free (struct prefix_ipv6 *p)
596{
ajs7907c6c2005-07-26 19:55:31 +0000597 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000598}
599
600/* If given string is valid return pin6 else return NULL */
601int
hassob04c6992004-10-04 19:10:31 +0000602str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000603{
604 char *pnt;
605 char *cp;
606 int ret;
607
608 pnt = strchr (str, '/');
609
610 /* If string doesn't contain `/' treat it as host route. */
611 if (pnt == NULL)
612 {
613 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100614 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000615 return 0;
616 p->prefixlen = IPV6_MAX_BITLEN;
617 }
618 else
619 {
620 int plen;
621
622 cp = XMALLOC (0, (pnt - str) + 1);
623 strncpy (cp, str, pnt - str);
624 *(cp + (pnt - str)) = '\0';
625 ret = inet_pton (AF_INET6, cp, &p->prefix);
626 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100627 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000628 return 0;
629 plen = (u_char) atoi (++pnt);
630 if (plen > 128)
631 return 0;
632 p->prefixlen = plen;
633 }
634 p->family = AF_INET6;
635
636 return ret;
637}
638
hassob04c6992004-10-04 19:10:31 +0000639/* Convert struct in6_addr netmask into integer.
640 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000641int
642ip6_masklen (struct in6_addr netmask)
643{
644 int len = 0;
645 unsigned char val;
646 unsigned char *pnt;
647
648 pnt = (unsigned char *) & netmask;
649
650 while ((*pnt == 0xff) && len < 128)
651 {
652 len += 8;
653 pnt++;
654 }
655
656 if (len < 128)
657 {
658 val = *pnt;
659 while (val)
660 {
661 len++;
662 val <<= 1;
663 }
664 }
665 return len;
666}
667
668void
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400669masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000670{
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400671 assert (masklen >=0 && masklen <= 128);
672 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000673}
674
675void
676apply_mask_ipv6 (struct prefix_ipv6 *p)
677{
678 u_char *pnt;
679 int index;
680 int offset;
681
682 index = p->prefixlen / 8;
683
684 if (index < 16)
685 {
686 pnt = (u_char *) &p->prefix;
687 offset = p->prefixlen % 8;
688
689 pnt[index] &= maskbit[offset];
690 index++;
691
692 while (index < 16)
693 pnt[index++] = 0;
694 }
695}
696
697void
hassob04c6992004-10-04 19:10:31 +0000698str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000699{
700 int i;
701 unsigned int x;
702
703 /* %x must point to unsinged int */
704 for (i = 0; i < 16; i++)
705 {
706 sscanf (str + (i * 2), "%02x", &x);
707 addr->s6_addr[i] = x & 0xff;
708 }
709}
710#endif /* HAVE_IPV6 */
711
712void
713apply_mask (struct prefix *p)
714{
715 switch (p->family)
716 {
717 case AF_INET:
718 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
719 break;
720#ifdef HAVE_IPV6
721 case AF_INET6:
722 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
723 break;
724#endif /* HAVE_IPV6 */
725 default:
726 break;
727 }
728 return;
729}
730
hassob04c6992004-10-04 19:10:31 +0000731/* Utility function of convert between struct prefix <=> union sockunion.
732 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000733struct prefix *
hassob04c6992004-10-04 19:10:31 +0000734sockunion2prefix (const union sockunion *dest,
735 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000736{
737 if (dest->sa.sa_family == AF_INET)
738 {
739 struct prefix_ipv4 *p;
740
741 p = prefix_ipv4_new ();
742 p->family = AF_INET;
743 p->prefix = dest->sin.sin_addr;
744 p->prefixlen = ip_masklen (mask->sin.sin_addr);
745 return (struct prefix *) p;
746 }
747#ifdef HAVE_IPV6
748 if (dest->sa.sa_family == AF_INET6)
749 {
750 struct prefix_ipv6 *p;
751
752 p = prefix_ipv6_new ();
753 p->family = AF_INET6;
754 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
755 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
756 return (struct prefix *) p;
757 }
758#endif /* HAVE_IPV6 */
759 return NULL;
760}
761
hassob04c6992004-10-04 19:10:31 +0000762/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000763struct prefix *
hassob04c6992004-10-04 19:10:31 +0000764sockunion2hostprefix (const union sockunion *su)
paul718e3742002-12-13 20:15:29 +0000765{
766 if (su->sa.sa_family == AF_INET)
767 {
768 struct prefix_ipv4 *p;
769
770 p = prefix_ipv4_new ();
771 p->family = AF_INET;
772 p->prefix = su->sin.sin_addr;
773 p->prefixlen = IPV4_MAX_BITLEN;
774 return (struct prefix *) p;
775 }
776#ifdef HAVE_IPV6
777 if (su->sa.sa_family == AF_INET6)
778 {
779 struct prefix_ipv6 *p;
780
781 p = prefix_ipv6_new ();
782 p->family = AF_INET6;
783 p->prefixlen = IPV6_MAX_BITLEN;
784 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
785 return (struct prefix *) p;
786 }
787#endif /* HAVE_IPV6 */
788 return NULL;
789}
790
David Lamparter17e52062010-02-02 20:16:35 +0100791void
792prefix2sockunion (const struct prefix *p, union sockunion *su)
793{
794 memset (su, 0, sizeof (*su));
795
796 su->sa.sa_family = p->family;
797 if (p->family == AF_INET)
798 su->sin.sin_addr = p->u.prefix4;
799#ifdef HAVE_IPV6
800 if (p->family == AF_INET6)
801 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
802#endif /* HAVE_IPV6 */
803}
804
paul718e3742002-12-13 20:15:29 +0000805int
hassob04c6992004-10-04 19:10:31 +0000806prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000807{
808 switch (p->family)
809 {
810 case AF_INET:
811 return IPV4_MAX_BYTELEN;
812 break;
813#ifdef HAVE_IPV6
814 case AF_INET6:
815 return IPV6_MAX_BYTELEN;
816 break;
817#endif /* HAVE_IPV6 */
818 }
819 return 0;
820}
821
822/* Generic function for conversion string to struct prefix. */
823int
hassob04c6992004-10-04 19:10:31 +0000824str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000825{
826 int ret;
827
828 /* First we try to convert string to struct prefix_ipv4. */
829 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
830 if (ret)
831 return ret;
832
833#ifdef HAVE_IPV6
834 /* Next we try to convert string to struct prefix_ipv6. */
835 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
836 if (ret)
837 return ret;
838#endif /* HAVE_IPV6 */
839
840 return 0;
841}
842
843int
hassob04c6992004-10-04 19:10:31 +0000844prefix2str (const struct prefix *p, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000845{
846 char buf[BUFSIZ];
847
848 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
849 snprintf (str, size, "%s/%d", buf, p->prefixlen);
850 return 0;
851}
852
853struct prefix *
854prefix_new ()
855{
856 struct prefix *p;
857
858 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
859 return p;
860}
861
862/* Free prefix structure. */
863void
864prefix_free (struct prefix *p)
865{
866 XFREE (MTYPE_PREFIX, p);
867}
868
869/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000870 * character.
871 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000872int
hassob04c6992004-10-04 19:10:31 +0000873all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000874{
875 for (; *str != '\0'; str++)
876 if (!isdigit ((int) *str))
877 return 0;
878 return 1;
879}
880
881/* Utility function to convert ipv4 prefixes to Classful prefixes */
882void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
883{
884
885 u_int32_t destination;
886
887 destination = ntohl (p->prefix.s_addr);
888
hasso3fb9cd62004-10-19 19:44:43 +0000889 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000890 /* do nothing for host routes */
891 else if (IN_CLASSC (destination))
892 {
893 p->prefixlen=24;
894 apply_mask_ipv4(p);
895 }
896 else if (IN_CLASSB(destination))
897 {
898 p->prefixlen=16;
899 apply_mask_ipv4(p);
900 }
901 else
902 {
903 p->prefixlen=8;
904 apply_mask_ipv4(p);
905 }
906}
907
hasso3fb9cd62004-10-19 19:44:43 +0000908in_addr_t
909ipv4_network_addr (in_addr_t hostaddr, int masklen)
910{
911 struct in_addr mask;
912
913 masklen2ip (masklen, &mask);
914 return hostaddr & mask.s_addr;
915}
916
917in_addr_t
918ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
919{
920 struct in_addr mask;
921
922 masklen2ip (masklen, &mask);
923 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
924 /* normal case */
925 (hostaddr | ~mask.s_addr) :
926 /* special case for /31 */
927 (hostaddr ^ ~mask.s_addr);
928}
929
paul718e3742002-12-13 20:15:29 +0000930/* Utility function to convert ipv4 netmask to prefixes
931 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
932 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
933int
hassob04c6992004-10-04 19:10:31 +0000934netmask_str2prefix_str (const char *net_str, const char *mask_str,
935 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000936{
937 struct in_addr network;
938 struct in_addr mask;
939 u_char prefixlen;
940 u_int32_t destination;
941 int ret;
942
943 ret = inet_aton (net_str, &network);
944 if (! ret)
945 return 0;
946
947 if (mask_str)
948 {
949 ret = inet_aton (mask_str, &mask);
950 if (! ret)
951 return 0;
952
953 prefixlen = ip_masklen (mask);
954 }
955 else
956 {
957 destination = ntohl (network.s_addr);
958
959 if (network.s_addr == 0)
960 prefixlen = 0;
961 else if (IN_CLASSC (destination))
962 prefixlen = 24;
963 else if (IN_CLASSB (destination))
964 prefixlen = 16;
965 else if (IN_CLASSA (destination))
966 prefixlen = 8;
967 else
968 return 0;
969 }
970
971 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
972
973 return 1;
974}
975
hasso59209902005-04-05 14:36:49 +0000976#ifdef HAVE_IPV6
977/* Utility function for making IPv6 address string. */
978const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000979inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000980{
981 static char buf[INET6_ADDRSTRLEN];
982
hasso3a2ce6a2005-04-08 01:30:51 +0000983 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000984 return buf;
985}
986#endif /* HAVE_IPV6 */