blob: 60e573a6db30bbf2b2c0164c26805cda9528932e [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};
Renato Westphalfe67e662012-03-23 16:27:40 -030034static const u_int32_t maskbytes_big_endian[] =
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};
Renato Westphalfe67e662012-03-23 16:27:40 -030070
71static const u_int32_t maskbytes_little_endian[] =
Denis Ovsienko051954f2011-10-11 15:17:45 +040072{
73 0x00000000, /* /0 0.0.0.0 */
74 0x00000080, /* /1 128.0.0.0 */
75 0x000000c0, /* /2 192.0.0.0 */
76 0x000000e0, /* /3 224.0.0.0 */
77 0x000000f0, /* /4 240.0.0.0 */
78 0x000000f8, /* /5 248.0.0.0 */
79 0x000000fc, /* /6 252.0.0.0 */
80 0x000000fe, /* /7 254.0.0.0 */
81 0x000000ff, /* /8 255.0.0.0 */
82 0x000080ff, /* /9 255.128.0.0 */
83 0x0000c0ff, /* /10 255.192.0.0 */
84 0x0000e0ff, /* /11 255.224.0.0 */
85 0x0000f0ff, /* /12 255.240.0.0 */
86 0x0000f8ff, /* /13 255.248.0.0 */
87 0x0000fcff, /* /14 255.252.0.0 */
88 0x0000feff, /* /15 255.254.0.0 */
89 0x0000ffff, /* /16 255.255.0.0 */
90 0x0080ffff, /* /17 255.255.128.0 */
91 0x00c0ffff, /* /18 255.255.192.0 */
92 0x00e0ffff, /* /19 255.255.224.0 */
93 0x00f0ffff, /* /20 255.255.240.0 */
94 0x00f8ffff, /* /21 255.255.248.0 */
95 0x00fcffff, /* /22 255.255.252.0 */
96 0x00feffff, /* /23 255.255.254.0 */
97 0x00ffffff, /* /24 255.255.255.0 */
98 0x80ffffff, /* /25 255.255.255.128 */
99 0xc0ffffff, /* /26 255.255.255.192 */
100 0xe0ffffff, /* /27 255.255.255.224 */
101 0xf0ffffff, /* /28 255.255.255.240 */
102 0xf8ffffff, /* /29 255.255.255.248 */
103 0xfcffffff, /* /30 255.255.255.252 */
104 0xfeffffff, /* /31 255.255.255.254 */
105 0xffffffff /* /32 255.255.255.255 */
106};
Renato Westphalfe67e662012-03-23 16:27:40 -0300107
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400108static const struct in6_addr maskbytes6[] =
109{
110 /* /0 */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
111 /* /1 */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
112 /* /2 */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
113 /* /3 */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
114 /* /4 */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
115 /* /5 */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
116 /* /6 */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
117 /* /7 */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
118 /* /8 */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
119 /* /9 */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
120 /* /10 */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
121 /* /11 */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
122 /* /12 */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
123 /* /13 */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
124 /* /14 */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
125 /* /15 */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
126 /* /16 */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
127 /* /17 */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
128 /* /18 */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
129 /* /19 */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
130 /* /20 */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
131 /* /21 */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
132 /* /22 */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
133 /* /23 */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
134 /* /24 */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
135 /* /25 */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
136 /* /26 */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
137 /* /27 */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
138 /* /28 */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
139 /* /29 */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
140 /* /30 */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
141 /* /31 */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
142 /* /32 */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
143 /* /33 */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
144 /* /34 */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
145 /* /35 */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
146 /* /36 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
147 /* /37 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
148 /* /38 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
149 /* /39 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
150 /* /40 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
151 /* /41 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
152 /* /42 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
153 /* /43 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
154 /* /44 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
155 /* /45 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
156 /* /46 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
157 /* /47 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
158 /* /48 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
159 /* /49 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
160 /* /50 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
161 /* /51 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
162 /* /52 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
163 /* /53 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
164 /* /54 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
165 /* /55 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
166 /* /56 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
167 /* /57 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
168 /* /58 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
169 /* /59 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
170 /* /60 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
171 /* /61 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
172 /* /62 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
173 /* /63 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
174 /* /64 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
175 /* /65 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
176 /* /66 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
177 /* /67 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
178 /* /68 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
179 /* /69 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
180 /* /70 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
181 /* /71 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
182 /* /72 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
183 /* /73 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
184 /* /74 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
185 /* /75 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
186 /* /76 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
187 /* /77 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
188 /* /78 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
189 /* /79 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
190 /* /80 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
191 /* /81 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
192 /* /82 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
193 /* /83 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
194 /* /84 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
195 /* /85 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
196 /* /86 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
197 /* /87 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
198 /* /88 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
199 /* /89 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } },
200 /* /90 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } },
201 /* /91 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } },
202 /* /92 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } },
203 /* /93 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } },
204 /* /94 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } },
205 /* /95 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } },
206 /* /96 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
207 /* /97 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } },
208 /* /98 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } },
209 /* /99 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } },
210 /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } },
211 /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } },
212 /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } },
213 /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } },
214 /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } },
215 /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } },
216 /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } },
217 /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } },
218 /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } },
219 /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } },
220 /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } },
221 /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } },
222 /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
223 /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } },
224 /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } },
225 /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } },
226 /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } },
227 /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } },
228 /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } },
229 /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } },
230 /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } },
231 /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } },
232 /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } },
233 /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } },
234 /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } },
235 /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } },
236 /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } },
237 /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } },
238 /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
239};
paul718e3742002-12-13 20:15:29 +0000240
241/* Number of bits in prefix type. */
242#ifndef PNBBY
243#define PNBBY 8
244#endif /* PNBBY */
245
246#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
247
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100248unsigned int
249prefix_bit (const u_char *prefix, const u_char prefixlen)
250{
251 unsigned int offset = prefixlen / 8;
252 unsigned int shift = 7 - (prefixlen % 8);
253
254 return (prefix[offset] >> shift) & 1;
255}
256
257unsigned int
258prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
259{
260 return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
261}
262
paul718e3742002-12-13 20:15:29 +0000263/* Address Famiy Identifier to Address Family converter. */
264int
Michael Lambert4c9641b2010-07-22 13:20:55 -0400265afi2family (afi_t afi)
paul718e3742002-12-13 20:15:29 +0000266{
267 if (afi == AFI_IP)
268 return AF_INET;
269#ifdef HAVE_IPV6
270 else if (afi == AFI_IP6)
271 return AF_INET6;
272#endif /* HAVE_IPV6 */
273 return 0;
274}
275
Michael Lambert4c9641b2010-07-22 13:20:55 -0400276afi_t
paul718e3742002-12-13 20:15:29 +0000277family2afi (int family)
278{
279 if (family == AF_INET)
280 return AFI_IP;
281#ifdef HAVE_IPV6
282 else if (family == AF_INET6)
283 return AFI_IP6;
284#endif /* HAVE_IPV6 */
285 return 0;
286}
287
288/* If n includes p prefix then return 1 else return 0. */
289int
hassob04c6992004-10-04 19:10:31 +0000290prefix_match (const struct prefix *n, const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000291{
292 int offset;
293 int shift;
Paul Jakmad3583442010-01-24 21:41:02 +0000294 const u_char *np, *pp;
paul718e3742002-12-13 20:15:29 +0000295
296 /* If n's prefix is longer than p's one return 0. */
297 if (n->prefixlen > p->prefixlen)
298 return 0;
299
Paul Jakmad3583442010-01-24 21:41:02 +0000300 /* Set both prefix's head pointer. */
301 np = (const u_char *)&n->u.prefix;
302 pp = (const u_char *)&p->u.prefix;
303
paul718e3742002-12-13 20:15:29 +0000304 offset = n->prefixlen / PNBBY;
305 shift = n->prefixlen % PNBBY;
306
307 if (shift)
308 if (maskbit[shift] & (np[offset] ^ pp[offset]))
309 return 0;
310
311 while (offset--)
312 if (np[offset] != pp[offset])
313 return 0;
314 return 1;
315}
316
317/* Copy prefix from src to dest. */
318void
hassob04c6992004-10-04 19:10:31 +0000319prefix_copy (struct prefix *dest, const struct prefix *src)
paul718e3742002-12-13 20:15:29 +0000320{
321 dest->family = src->family;
322 dest->prefixlen = src->prefixlen;
323
324 if (src->family == AF_INET)
325 dest->u.prefix4 = src->u.prefix4;
326#ifdef HAVE_IPV6
327 else if (src->family == AF_INET6)
328 dest->u.prefix6 = src->u.prefix6;
329#endif /* HAVE_IPV6 */
330 else if (src->family == AF_UNSPEC)
331 {
332 dest->u.lp.id = src->u.lp.id;
333 dest->u.lp.adv_router = src->u.lp.adv_router;
334 }
335 else
336 {
ajsb9e70282004-12-08 17:14:45 +0000337 zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
paul718e3742002-12-13 20:15:29 +0000338 src->family);
339 assert (0);
340 }
341}
342
gdt9d24baa2004-01-13 14:55:40 +0000343/*
344 * Return 1 if the address/netmask contained in the prefix structure
345 * is the same, and else return 0. For this routine, 'same' requires
346 * that not only the prefix length and the network part be the same,
347 * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
348 * the same. Note that this routine has the same return value sense
349 * as '==' (which is different from prefix_cmp).
350 */
paul718e3742002-12-13 20:15:29 +0000351int
hassob04c6992004-10-04 19:10:31 +0000352prefix_same (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000353{
354 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
355 {
356 if (p1->family == AF_INET)
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400357 if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
paul718e3742002-12-13 20:15:29 +0000358 return 1;
359#ifdef HAVE_IPV6
360 if (p1->family == AF_INET6 )
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400361 if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
paul718e3742002-12-13 20:15:29 +0000362 return 1;
363#endif /* HAVE_IPV6 */
364 }
365 return 0;
366}
367
gdt9d24baa2004-01-13 14:55:40 +0000368/*
369 * Return 0 if the network prefixes represented by the struct prefix
370 * arguments are the same prefix, and 1 otherwise. Network prefixes
371 * are considered the same if the prefix lengths are equal and the
372 * network parts are the same. Host bits (which are considered masked
373 * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
374 * 10.0.0.2/8 are considered equivalent by this routine. Note that
375 * this routine has the same return sense as strcmp (which is different
376 * from prefix_same).
377 */
paul718e3742002-12-13 20:15:29 +0000378int
hassob04c6992004-10-04 19:10:31 +0000379prefix_cmp (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000380{
381 int offset;
382 int shift;
383
384 /* Set both prefix's head pointer. */
paul8cc41982005-05-06 21:25:49 +0000385 const u_char *pp1 = (const u_char *)&p1->u.prefix;
386 const u_char *pp2 = (const u_char *)&p2->u.prefix;
paul718e3742002-12-13 20:15:29 +0000387
388 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
389 return 1;
390
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400391 offset = p1->prefixlen / PNBBY;
392 shift = p1->prefixlen % PNBBY;
paul718e3742002-12-13 20:15:29 +0000393
394 if (shift)
395 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
396 return 1;
397
398 while (offset--)
399 if (pp1[offset] != pp2[offset])
400 return 1;
401
402 return 0;
403}
404
David Lamparter17e52062010-02-02 20:16:35 +0100405/*
406 * Count the number of common bits in 2 prefixes. The prefix length is
407 * ignored for this function; the whole prefix is compared. If the prefix
408 * address families don't match, return -1; otherwise the return value is
409 * in range 0 ... maximum prefix length for the address family.
410 */
411int
412prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
413{
414 int pos, bit;
415 int length = 0;
416 u_char xor;
417
418 /* Set both prefix's head pointer. */
419 const u_char *pp1 = (const u_char *)&p1->u.prefix;
420 const u_char *pp2 = (const u_char *)&p2->u.prefix;
421
422 if (p1->family == AF_INET)
423 length = IPV4_MAX_BYTELEN;
424#ifdef HAVE_IPV6
425 if (p1->family == AF_INET6)
426 length = IPV6_MAX_BYTELEN;
427#endif
428 if (p1->family != p2->family || !length)
429 return -1;
430
431 for (pos = 0; pos < length; pos++)
432 if (pp1[pos] != pp2[pos])
433 break;
434 if (pos == length)
435 return pos * 8;
436
437 xor = pp1[pos] ^ pp2[pos];
438 for (bit = 0; bit < 8; bit++)
439 if (xor & (1 << (7 - bit)))
440 break;
441
442 return pos * 8 + bit;
443}
444
paul718e3742002-12-13 20:15:29 +0000445/* Return prefix family type string. */
hassob04c6992004-10-04 19:10:31 +0000446const char *
447prefix_family_str (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000448{
449 if (p->family == AF_INET)
450 return "inet";
451#ifdef HAVE_IPV6
452 if (p->family == AF_INET6)
453 return "inet6";
454#endif /* HAVE_IPV6 */
455 return "unspec";
456}
457
458/* Allocate new prefix_ipv4 structure. */
459struct prefix_ipv4 *
460prefix_ipv4_new ()
461{
462 struct prefix_ipv4 *p;
463
ajs7907c6c2005-07-26 19:55:31 +0000464 /* Call prefix_new to allocate a full-size struct prefix to avoid problems
465 where the struct prefix_ipv4 is cast to struct prefix and unallocated
466 bytes were being referenced (e.g. in structure assignments). */
467 p = (struct prefix_ipv4 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000468 p->family = AF_INET;
469 return p;
470}
471
472/* Free prefix_ipv4 structure. */
473void
474prefix_ipv4_free (struct prefix_ipv4 *p)
475{
ajs7907c6c2005-07-26 19:55:31 +0000476 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000477}
478
479/* When string format is invalid return 0. */
480int
hassob04c6992004-10-04 19:10:31 +0000481str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000482{
483 int ret;
484 int plen;
485 char *pnt;
486 char *cp;
487
488 /* Find slash inside string. */
489 pnt = strchr (str, '/');
490
491 /* String doesn't contail slash. */
492 if (pnt == NULL)
493 {
494 /* Convert string to prefix. */
495 ret = inet_aton (str, &p->prefix);
496 if (ret == 0)
497 return 0;
498
499 /* If address doesn't contain slash we assume it host address. */
500 p->family = AF_INET;
501 p->prefixlen = IPV4_MAX_BITLEN;
502
503 return ret;
504 }
505 else
506 {
507 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
508 strncpy (cp, str, pnt - str);
509 *(cp + (pnt - str)) = '\0';
510 ret = inet_aton (cp, &p->prefix);
511 XFREE (MTYPE_TMP, cp);
512
513 /* Get prefix length. */
514 plen = (u_char) atoi (++pnt);
hasso3fb9cd62004-10-19 19:44:43 +0000515 if (plen > IPV4_MAX_PREFIXLEN)
paul718e3742002-12-13 20:15:29 +0000516 return 0;
517
518 p->family = AF_INET;
519 p->prefixlen = plen;
520 }
521
522 return ret;
523}
524
Denis Ovsienko051954f2011-10-11 15:17:45 +0400525/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000526void
Denis Ovsienko96633862011-10-08 18:15:21 +0400527masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000528{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400529 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
Renato Westphalfe67e662012-03-23 16:27:40 -0300530#if (BYTE_ORDER == LITTLE_ENDIAN)
531 netmask->s_addr = maskbytes_little_endian[masklen];
532#elif (BYTE_ORDER == BIG_ENDIAN)
533 netmask->s_addr = maskbytes_big_endian[masklen];
534#endif
paul718e3742002-12-13 20:15:29 +0000535}
536
537/* Convert IP address's netmask into integer. We assume netmask is
538 sequential one. Argument netmask should be network byte order. */
539u_char
540ip_masklen (struct in_addr netmask)
541{
David Lampartera3537862012-03-23 22:48:05 +0100542 u_char len;
543 u_char *pnt;
544 u_char *end;
545 u_char val;
546
547 len = 0;
548 pnt = (u_char *) &netmask;
549 end = pnt + 4;
550
551 while ((pnt < end) && (*pnt == 0xff))
552 {
553 len+= 8;
554 pnt++;
555 }
556
557 if (pnt < end)
558 {
559 val = *pnt;
560 while (val)
561 {
562 len++;
563 val <<= 1;
564 }
565 }
566 return len;
paul718e3742002-12-13 20:15:29 +0000567}
568
Denis Ovsienkocaff7902011-10-18 18:33:53 +0400569/* Apply mask to IPv4 prefix (network byte order). */
paul718e3742002-12-13 20:15:29 +0000570void
571apply_mask_ipv4 (struct prefix_ipv4 *p)
572{
Denis Ovsienkocaff7902011-10-18 18:33:53 +0400573 assert (p->prefixlen >= 0 && p->prefixlen <= IPV4_MAX_BITLEN);
Renato Westphalfe67e662012-03-23 16:27:40 -0300574#if (BYTE_ORDER == LITTLE_ENDIAN)
575 p->prefix.s_addr &= maskbytes_little_endian[p->prefixlen];
576#elif (BYTE_ORDER == BIG_ENDIAN)
577 p->prefix.s_addr &= maskbytes_big_endian[p->prefixlen];
578#endif
paul718e3742002-12-13 20:15:29 +0000579}
580
581/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
582int
hassob04c6992004-10-04 19:10:31 +0000583prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000584{
585 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
586}
587
588#ifdef HAVE_IPV6
589
590/* Allocate a new ip version 6 route */
591struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000592prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000593{
594 struct prefix_ipv6 *p;
595
ajs7907c6c2005-07-26 19:55:31 +0000596 /* Allocate a full-size struct prefix to avoid problems with structure
597 size mismatches. */
598 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000599 p->family = AF_INET6;
600 return p;
601}
602
603/* Free prefix for IPv6. */
604void
605prefix_ipv6_free (struct prefix_ipv6 *p)
606{
ajs7907c6c2005-07-26 19:55:31 +0000607 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000608}
609
610/* If given string is valid return pin6 else return NULL */
611int
hassob04c6992004-10-04 19:10:31 +0000612str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000613{
614 char *pnt;
615 char *cp;
616 int ret;
617
618 pnt = strchr (str, '/');
619
620 /* If string doesn't contain `/' treat it as host route. */
621 if (pnt == NULL)
622 {
623 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100624 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000625 return 0;
626 p->prefixlen = IPV6_MAX_BITLEN;
627 }
628 else
629 {
630 int plen;
631
632 cp = XMALLOC (0, (pnt - str) + 1);
633 strncpy (cp, str, pnt - str);
634 *(cp + (pnt - str)) = '\0';
635 ret = inet_pton (AF_INET6, cp, &p->prefix);
636 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100637 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000638 return 0;
639 plen = (u_char) atoi (++pnt);
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400640 if (plen > IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000641 return 0;
642 p->prefixlen = plen;
643 }
644 p->family = AF_INET6;
645
646 return ret;
647}
648
hassob04c6992004-10-04 19:10:31 +0000649/* Convert struct in6_addr netmask into integer.
650 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000651int
652ip6_masklen (struct in6_addr netmask)
653{
654 int len = 0;
655 unsigned char val;
656 unsigned char *pnt;
657
658 pnt = (unsigned char *) & netmask;
659
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400660 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000661 {
662 len += 8;
663 pnt++;
664 }
665
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400666 if (len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000667 {
668 val = *pnt;
669 while (val)
670 {
671 len++;
672 val <<= 1;
673 }
674 }
675 return len;
676}
677
678void
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400679masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000680{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400681 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400682 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000683}
684
685void
686apply_mask_ipv6 (struct prefix_ipv6 *p)
687{
Denis Ovsienko8c7f49d2012-01-01 16:33:12 +0400688 u_char *pnt;
689 int index;
690 int offset;
691
692 index = p->prefixlen / 8;
693
694 if (index < 16)
695 {
696 pnt = (u_char *) &p->prefix;
697 offset = p->prefixlen % 8;
698
699 pnt[index] &= maskbit[offset];
700 index++;
701
702 while (index < 16)
703 pnt[index++] = 0;
704 }
paul718e3742002-12-13 20:15:29 +0000705}
706
707void
hassob04c6992004-10-04 19:10:31 +0000708str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000709{
710 int i;
711 unsigned int x;
712
713 /* %x must point to unsinged int */
714 for (i = 0; i < 16; i++)
715 {
716 sscanf (str + (i * 2), "%02x", &x);
717 addr->s6_addr[i] = x & 0xff;
718 }
719}
720#endif /* HAVE_IPV6 */
721
722void
723apply_mask (struct prefix *p)
724{
725 switch (p->family)
726 {
727 case AF_INET:
728 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
729 break;
730#ifdef HAVE_IPV6
731 case AF_INET6:
732 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
733 break;
734#endif /* HAVE_IPV6 */
735 default:
736 break;
737 }
738 return;
739}
740
hassob04c6992004-10-04 19:10:31 +0000741/* Utility function of convert between struct prefix <=> union sockunion.
742 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000743struct prefix *
hassob04c6992004-10-04 19:10:31 +0000744sockunion2prefix (const union sockunion *dest,
745 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000746{
747 if (dest->sa.sa_family == AF_INET)
748 {
749 struct prefix_ipv4 *p;
750
751 p = prefix_ipv4_new ();
752 p->family = AF_INET;
753 p->prefix = dest->sin.sin_addr;
754 p->prefixlen = ip_masklen (mask->sin.sin_addr);
755 return (struct prefix *) p;
756 }
757#ifdef HAVE_IPV6
758 if (dest->sa.sa_family == AF_INET6)
759 {
760 struct prefix_ipv6 *p;
761
762 p = prefix_ipv6_new ();
763 p->family = AF_INET6;
764 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
765 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
766 return (struct prefix *) p;
767 }
768#endif /* HAVE_IPV6 */
769 return NULL;
770}
771
hassob04c6992004-10-04 19:10:31 +0000772/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000773struct prefix *
hassob04c6992004-10-04 19:10:31 +0000774sockunion2hostprefix (const union sockunion *su)
paul718e3742002-12-13 20:15:29 +0000775{
776 if (su->sa.sa_family == AF_INET)
777 {
778 struct prefix_ipv4 *p;
779
780 p = prefix_ipv4_new ();
781 p->family = AF_INET;
782 p->prefix = su->sin.sin_addr;
783 p->prefixlen = IPV4_MAX_BITLEN;
784 return (struct prefix *) p;
785 }
786#ifdef HAVE_IPV6
787 if (su->sa.sa_family == AF_INET6)
788 {
789 struct prefix_ipv6 *p;
790
791 p = prefix_ipv6_new ();
792 p->family = AF_INET6;
793 p->prefixlen = IPV6_MAX_BITLEN;
794 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
795 return (struct prefix *) p;
796 }
797#endif /* HAVE_IPV6 */
798 return NULL;
799}
800
David Lamparter17e52062010-02-02 20:16:35 +0100801void
802prefix2sockunion (const struct prefix *p, union sockunion *su)
803{
804 memset (su, 0, sizeof (*su));
805
806 su->sa.sa_family = p->family;
807 if (p->family == AF_INET)
808 su->sin.sin_addr = p->u.prefix4;
809#ifdef HAVE_IPV6
810 if (p->family == AF_INET6)
811 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
812#endif /* HAVE_IPV6 */
813}
814
paul718e3742002-12-13 20:15:29 +0000815int
hassob04c6992004-10-04 19:10:31 +0000816prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000817{
818 switch (p->family)
819 {
820 case AF_INET:
821 return IPV4_MAX_BYTELEN;
822 break;
823#ifdef HAVE_IPV6
824 case AF_INET6:
825 return IPV6_MAX_BYTELEN;
826 break;
827#endif /* HAVE_IPV6 */
828 }
829 return 0;
830}
831
832/* Generic function for conversion string to struct prefix. */
833int
hassob04c6992004-10-04 19:10:31 +0000834str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000835{
836 int ret;
837
838 /* First we try to convert string to struct prefix_ipv4. */
839 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
840 if (ret)
841 return ret;
842
843#ifdef HAVE_IPV6
844 /* Next we try to convert string to struct prefix_ipv6. */
845 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
846 if (ret)
847 return ret;
848#endif /* HAVE_IPV6 */
849
850 return 0;
851}
852
853int
hassob04c6992004-10-04 19:10:31 +0000854prefix2str (const struct prefix *p, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000855{
856 char buf[BUFSIZ];
857
858 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
859 snprintf (str, size, "%s/%d", buf, p->prefixlen);
860 return 0;
861}
862
863struct prefix *
864prefix_new ()
865{
866 struct prefix *p;
867
868 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
869 return p;
870}
871
872/* Free prefix structure. */
873void
874prefix_free (struct prefix *p)
875{
876 XFREE (MTYPE_PREFIX, p);
877}
878
879/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000880 * character.
881 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000882int
hassob04c6992004-10-04 19:10:31 +0000883all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000884{
885 for (; *str != '\0'; str++)
886 if (!isdigit ((int) *str))
887 return 0;
888 return 1;
889}
890
891/* Utility function to convert ipv4 prefixes to Classful prefixes */
892void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
893{
894
895 u_int32_t destination;
896
897 destination = ntohl (p->prefix.s_addr);
898
hasso3fb9cd62004-10-19 19:44:43 +0000899 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000900 /* do nothing for host routes */
901 else if (IN_CLASSC (destination))
902 {
903 p->prefixlen=24;
904 apply_mask_ipv4(p);
905 }
906 else if (IN_CLASSB(destination))
907 {
908 p->prefixlen=16;
909 apply_mask_ipv4(p);
910 }
911 else
912 {
913 p->prefixlen=8;
914 apply_mask_ipv4(p);
915 }
916}
917
hasso3fb9cd62004-10-19 19:44:43 +0000918in_addr_t
919ipv4_network_addr (in_addr_t hostaddr, int masklen)
920{
921 struct in_addr mask;
922
923 masklen2ip (masklen, &mask);
924 return hostaddr & mask.s_addr;
925}
926
927in_addr_t
928ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
929{
930 struct in_addr mask;
931
932 masklen2ip (masklen, &mask);
933 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
934 /* normal case */
935 (hostaddr | ~mask.s_addr) :
936 /* special case for /31 */
937 (hostaddr ^ ~mask.s_addr);
938}
939
paul718e3742002-12-13 20:15:29 +0000940/* Utility function to convert ipv4 netmask to prefixes
941 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
942 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
943int
hassob04c6992004-10-04 19:10:31 +0000944netmask_str2prefix_str (const char *net_str, const char *mask_str,
945 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000946{
947 struct in_addr network;
948 struct in_addr mask;
949 u_char prefixlen;
950 u_int32_t destination;
951 int ret;
952
953 ret = inet_aton (net_str, &network);
954 if (! ret)
955 return 0;
956
957 if (mask_str)
958 {
959 ret = inet_aton (mask_str, &mask);
960 if (! ret)
961 return 0;
962
963 prefixlen = ip_masklen (mask);
964 }
965 else
966 {
967 destination = ntohl (network.s_addr);
968
969 if (network.s_addr == 0)
970 prefixlen = 0;
971 else if (IN_CLASSC (destination))
972 prefixlen = 24;
973 else if (IN_CLASSB (destination))
974 prefixlen = 16;
975 else if (IN_CLASSA (destination))
976 prefixlen = 8;
977 else
978 return 0;
979 }
980
981 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
982
983 return 1;
984}
985
hasso59209902005-04-05 14:36:49 +0000986#ifdef HAVE_IPV6
987/* Utility function for making IPv6 address string. */
988const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000989inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000990{
991 static char buf[INET6_ADDRSTRLEN];
992
hasso3a2ce6a2005-04-08 01:30:51 +0000993 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000994 return buf;
995}
996#endif /* HAVE_IPV6 */