blob: 936e9fcb2b8b8b58d874bb104edd2a9e44e359e0 [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"
David Lamparter6b0655a2014-06-04 06:53:35 +020030
paul718e3742002-12-13 20:15:29 +000031/* 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 -030034
Denis Ovsienko21f569e2011-10-17 21:11:10 +040035static const struct in6_addr maskbytes6[] =
36{
37 /* /0 */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
38 /* /1 */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
39 /* /2 */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
40 /* /3 */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
41 /* /4 */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
42 /* /5 */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
43 /* /6 */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
44 /* /7 */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
45 /* /8 */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
46 /* /9 */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
47 /* /10 */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
48 /* /11 */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
49 /* /12 */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
50 /* /13 */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
51 /* /14 */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
52 /* /15 */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
53 /* /16 */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
54 /* /17 */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
55 /* /18 */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
56 /* /19 */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
57 /* /20 */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
58 /* /21 */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
59 /* /22 */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
60 /* /23 */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
61 /* /24 */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
62 /* /25 */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
63 /* /26 */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
64 /* /27 */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
65 /* /28 */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
66 /* /29 */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
67 /* /30 */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
68 /* /31 */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
69 /* /32 */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
70 /* /33 */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
71 /* /34 */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
72 /* /35 */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
73 /* /36 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
74 /* /37 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
75 /* /38 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
76 /* /39 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
77 /* /40 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
78 /* /41 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
79 /* /42 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
80 /* /43 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
81 /* /44 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
82 /* /45 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
83 /* /46 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
84 /* /47 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
85 /* /48 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
86 /* /49 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
87 /* /50 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
88 /* /51 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
89 /* /52 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
90 /* /53 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
91 /* /54 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
92 /* /55 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
93 /* /56 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
94 /* /57 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
95 /* /58 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
96 /* /59 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
97 /* /60 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
98 /* /61 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
99 /* /62 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
100 /* /63 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
101 /* /64 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
102 /* /65 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
103 /* /66 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
104 /* /67 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
105 /* /68 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
106 /* /69 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
107 /* /70 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
108 /* /71 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
109 /* /72 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
110 /* /73 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
111 /* /74 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
112 /* /75 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
113 /* /76 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
114 /* /77 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
115 /* /78 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
116 /* /79 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
117 /* /80 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
118 /* /81 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
119 /* /82 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
120 /* /83 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
121 /* /84 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
122 /* /85 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
123 /* /86 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
124 /* /87 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
125 /* /88 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
126 /* /89 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } },
127 /* /90 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } },
128 /* /91 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } },
129 /* /92 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } },
130 /* /93 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } },
131 /* /94 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } },
132 /* /95 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } },
133 /* /96 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
134 /* /97 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } },
135 /* /98 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } },
136 /* /99 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } },
137 /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } },
138 /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } },
139 /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } },
140 /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } },
141 /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } },
142 /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } },
143 /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } },
144 /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } },
145 /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } },
146 /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } },
147 /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } },
148 /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } },
149 /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
150 /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } },
151 /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } },
152 /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } },
153 /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } },
154 /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } },
155 /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } },
156 /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } },
157 /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } },
158 /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } },
159 /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } },
160 /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } },
161 /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } },
162 /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } },
163 /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } },
164 /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } },
165 /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
166};
paul718e3742002-12-13 20:15:29 +0000167
168/* Number of bits in prefix type. */
169#ifndef PNBBY
170#define PNBBY 8
171#endif /* PNBBY */
172
173#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
174
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100175unsigned int
176prefix_bit (const u_char *prefix, const u_char prefixlen)
177{
178 unsigned int offset = prefixlen / 8;
179 unsigned int shift = 7 - (prefixlen % 8);
180
181 return (prefix[offset] >> shift) & 1;
182}
183
184unsigned int
185prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
186{
187 return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
188}
David Lamparter6b0655a2014-06-04 06:53:35 +0200189
Christian Frankeacf98652015-11-12 14:24:22 +0100190int
191str2family(const char *string)
192{
193 if (!strcmp("ipv4", string))
194 return AF_INET;
195 else if (!strcmp("ipv6", string))
196 return AF_INET6;
197 else
198 return -1;
199}
200
paul718e3742002-12-13 20:15:29 +0000201/* Address Famiy Identifier to Address Family converter. */
202int
Michael Lambert4c9641b2010-07-22 13:20:55 -0400203afi2family (afi_t afi)
paul718e3742002-12-13 20:15:29 +0000204{
205 if (afi == AFI_IP)
206 return AF_INET;
207#ifdef HAVE_IPV6
208 else if (afi == AFI_IP6)
209 return AF_INET6;
210#endif /* HAVE_IPV6 */
211 return 0;
212}
213
Michael Lambert4c9641b2010-07-22 13:20:55 -0400214afi_t
paul718e3742002-12-13 20:15:29 +0000215family2afi (int family)
216{
217 if (family == AF_INET)
218 return AFI_IP;
219#ifdef HAVE_IPV6
220 else if (family == AF_INET6)
221 return AFI_IP6;
222#endif /* HAVE_IPV6 */
223 return 0;
224}
225
226/* If n includes p prefix then return 1 else return 0. */
227int
hassob04c6992004-10-04 19:10:31 +0000228prefix_match (const struct prefix *n, const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000229{
230 int offset;
231 int shift;
Paul Jakmad3583442010-01-24 21:41:02 +0000232 const u_char *np, *pp;
paul718e3742002-12-13 20:15:29 +0000233
234 /* If n's prefix is longer than p's one return 0. */
235 if (n->prefixlen > p->prefixlen)
236 return 0;
237
Paul Jakmad3583442010-01-24 21:41:02 +0000238 /* Set both prefix's head pointer. */
239 np = (const u_char *)&n->u.prefix;
240 pp = (const u_char *)&p->u.prefix;
241
paul718e3742002-12-13 20:15:29 +0000242 offset = n->prefixlen / PNBBY;
243 shift = n->prefixlen % PNBBY;
244
245 if (shift)
246 if (maskbit[shift] & (np[offset] ^ pp[offset]))
247 return 0;
248
249 while (offset--)
250 if (np[offset] != pp[offset])
251 return 0;
252 return 1;
253}
254
255/* Copy prefix from src to dest. */
256void
hassob04c6992004-10-04 19:10:31 +0000257prefix_copy (struct prefix *dest, const struct prefix *src)
paul718e3742002-12-13 20:15:29 +0000258{
259 dest->family = src->family;
260 dest->prefixlen = src->prefixlen;
261
262 if (src->family == AF_INET)
263 dest->u.prefix4 = src->u.prefix4;
264#ifdef HAVE_IPV6
265 else if (src->family == AF_INET6)
266 dest->u.prefix6 = src->u.prefix6;
267#endif /* HAVE_IPV6 */
268 else if (src->family == AF_UNSPEC)
269 {
270 dest->u.lp.id = src->u.lp.id;
271 dest->u.lp.adv_router = src->u.lp.adv_router;
272 }
273 else
274 {
ajsb9e70282004-12-08 17:14:45 +0000275 zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
paul718e3742002-12-13 20:15:29 +0000276 src->family);
277 assert (0);
278 }
279}
280
gdt9d24baa2004-01-13 14:55:40 +0000281/*
282 * Return 1 if the address/netmask contained in the prefix structure
283 * is the same, and else return 0. For this routine, 'same' requires
284 * that not only the prefix length and the network part be the same,
285 * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
286 * the same. Note that this routine has the same return value sense
287 * as '==' (which is different from prefix_cmp).
288 */
paul718e3742002-12-13 20:15:29 +0000289int
hassob04c6992004-10-04 19:10:31 +0000290prefix_same (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000291{
292 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
293 {
294 if (p1->family == AF_INET)
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400295 if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
paul718e3742002-12-13 20:15:29 +0000296 return 1;
297#ifdef HAVE_IPV6
298 if (p1->family == AF_INET6 )
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400299 if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
paul718e3742002-12-13 20:15:29 +0000300 return 1;
301#endif /* HAVE_IPV6 */
302 }
303 return 0;
304}
305
gdt9d24baa2004-01-13 14:55:40 +0000306/*
307 * Return 0 if the network prefixes represented by the struct prefix
308 * arguments are the same prefix, and 1 otherwise. Network prefixes
309 * are considered the same if the prefix lengths are equal and the
310 * network parts are the same. Host bits (which are considered masked
311 * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
312 * 10.0.0.2/8 are considered equivalent by this routine. Note that
313 * this routine has the same return sense as strcmp (which is different
314 * from prefix_same).
315 */
paul718e3742002-12-13 20:15:29 +0000316int
hassob04c6992004-10-04 19:10:31 +0000317prefix_cmp (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000318{
319 int offset;
320 int shift;
321
322 /* Set both prefix's head pointer. */
paul8cc41982005-05-06 21:25:49 +0000323 const u_char *pp1 = (const u_char *)&p1->u.prefix;
324 const u_char *pp2 = (const u_char *)&p2->u.prefix;
paul718e3742002-12-13 20:15:29 +0000325
326 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
327 return 1;
328
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400329 offset = p1->prefixlen / PNBBY;
330 shift = p1->prefixlen % PNBBY;
paul718e3742002-12-13 20:15:29 +0000331
332 if (shift)
333 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
334 return 1;
335
336 while (offset--)
337 if (pp1[offset] != pp2[offset])
338 return 1;
339
340 return 0;
341}
342
David Lamparter17e52062010-02-02 20:16:35 +0100343/*
344 * Count the number of common bits in 2 prefixes. The prefix length is
345 * ignored for this function; the whole prefix is compared. If the prefix
346 * address families don't match, return -1; otherwise the return value is
347 * in range 0 ... maximum prefix length for the address family.
348 */
349int
350prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
351{
352 int pos, bit;
353 int length = 0;
354 u_char xor;
355
356 /* Set both prefix's head pointer. */
357 const u_char *pp1 = (const u_char *)&p1->u.prefix;
358 const u_char *pp2 = (const u_char *)&p2->u.prefix;
359
360 if (p1->family == AF_INET)
361 length = IPV4_MAX_BYTELEN;
362#ifdef HAVE_IPV6
363 if (p1->family == AF_INET6)
364 length = IPV6_MAX_BYTELEN;
365#endif
366 if (p1->family != p2->family || !length)
367 return -1;
368
369 for (pos = 0; pos < length; pos++)
370 if (pp1[pos] != pp2[pos])
371 break;
372 if (pos == length)
373 return pos * 8;
374
375 xor = pp1[pos] ^ pp2[pos];
376 for (bit = 0; bit < 8; bit++)
377 if (xor & (1 << (7 - bit)))
378 break;
379
380 return pos * 8 + bit;
381}
382
paul718e3742002-12-13 20:15:29 +0000383/* Return prefix family type string. */
hassob04c6992004-10-04 19:10:31 +0000384const char *
385prefix_family_str (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000386{
387 if (p->family == AF_INET)
388 return "inet";
389#ifdef HAVE_IPV6
390 if (p->family == AF_INET6)
391 return "inet6";
392#endif /* HAVE_IPV6 */
393 return "unspec";
394}
395
396/* Allocate new prefix_ipv4 structure. */
397struct prefix_ipv4 *
398prefix_ipv4_new ()
399{
400 struct prefix_ipv4 *p;
401
ajs7907c6c2005-07-26 19:55:31 +0000402 /* Call prefix_new to allocate a full-size struct prefix to avoid problems
403 where the struct prefix_ipv4 is cast to struct prefix and unallocated
404 bytes were being referenced (e.g. in structure assignments). */
405 p = (struct prefix_ipv4 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000406 p->family = AF_INET;
407 return p;
408}
409
410/* Free prefix_ipv4 structure. */
411void
412prefix_ipv4_free (struct prefix_ipv4 *p)
413{
ajs7907c6c2005-07-26 19:55:31 +0000414 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000415}
416
417/* When string format is invalid return 0. */
418int
hassob04c6992004-10-04 19:10:31 +0000419str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000420{
421 int ret;
422 int plen;
423 char *pnt;
424 char *cp;
425
426 /* Find slash inside string. */
427 pnt = strchr (str, '/');
428
429 /* String doesn't contail slash. */
430 if (pnt == NULL)
431 {
432 /* Convert string to prefix. */
433 ret = inet_aton (str, &p->prefix);
434 if (ret == 0)
435 return 0;
436
437 /* If address doesn't contain slash we assume it host address. */
438 p->family = AF_INET;
439 p->prefixlen = IPV4_MAX_BITLEN;
440
441 return ret;
442 }
443 else
444 {
445 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
446 strncpy (cp, str, pnt - str);
447 *(cp + (pnt - str)) = '\0';
448 ret = inet_aton (cp, &p->prefix);
449 XFREE (MTYPE_TMP, cp);
450
451 /* Get prefix length. */
452 plen = (u_char) atoi (++pnt);
hasso3fb9cd62004-10-19 19:44:43 +0000453 if (plen > IPV4_MAX_PREFIXLEN)
paul718e3742002-12-13 20:15:29 +0000454 return 0;
455
456 p->family = AF_INET;
457 p->prefixlen = plen;
458 }
459
460 return ret;
461}
462
Denis Ovsienko051954f2011-10-11 15:17:45 +0400463/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000464void
Denis Ovsienko96633862011-10-08 18:15:21 +0400465masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000466{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400467 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
David Lampartere96b3122012-04-04 00:14:36 +0200468
469 /* left shift is only defined for less than the size of the type.
470 * we unconditionally use long long in case the target platform
471 * has defined behaviour for << 32 (or has a 64-bit left shift) */
472
473 if (sizeof(unsigned long long) > 4)
474 netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
475 else
476 netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
paul718e3742002-12-13 20:15:29 +0000477}
478
479/* Convert IP address's netmask into integer. We assume netmask is
480 sequential one. Argument netmask should be network byte order. */
481u_char
482ip_masklen (struct in_addr netmask)
483{
David Lampartere96b3122012-04-04 00:14:36 +0200484 uint32_t tmp = ~ntohl(netmask.s_addr);
485 if (tmp)
486 /* clz: count leading zeroes. sadly, the behaviour of this builtin
487 * is undefined for a 0 argument, even though most CPUs give 32 */
488 return __builtin_clz(tmp);
489 else
490 return 32;
paul718e3742002-12-13 20:15:29 +0000491}
492
Denis Ovsienkocaff7902011-10-18 18:33:53 +0400493/* Apply mask to IPv4 prefix (network byte order). */
paul718e3742002-12-13 20:15:29 +0000494void
495apply_mask_ipv4 (struct prefix_ipv4 *p)
496{
David Lampartere96b3122012-04-04 00:14:36 +0200497 struct in_addr mask;
498 masklen2ip(p->prefixlen, &mask);
499 p->prefix.s_addr &= mask.s_addr;
paul718e3742002-12-13 20:15:29 +0000500}
501
502/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
503int
hassob04c6992004-10-04 19:10:31 +0000504prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000505{
506 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
507}
David Lamparter6b0655a2014-06-04 06:53:35 +0200508
paul718e3742002-12-13 20:15:29 +0000509#ifdef HAVE_IPV6
510
511/* Allocate a new ip version 6 route */
512struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000513prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000514{
515 struct prefix_ipv6 *p;
516
ajs7907c6c2005-07-26 19:55:31 +0000517 /* Allocate a full-size struct prefix to avoid problems with structure
518 size mismatches. */
519 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000520 p->family = AF_INET6;
521 return p;
522}
523
524/* Free prefix for IPv6. */
525void
526prefix_ipv6_free (struct prefix_ipv6 *p)
527{
ajs7907c6c2005-07-26 19:55:31 +0000528 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000529}
530
531/* If given string is valid return pin6 else return NULL */
532int
hassob04c6992004-10-04 19:10:31 +0000533str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000534{
535 char *pnt;
536 char *cp;
537 int ret;
538
539 pnt = strchr (str, '/');
540
541 /* If string doesn't contain `/' treat it as host route. */
542 if (pnt == NULL)
543 {
544 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100545 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000546 return 0;
547 p->prefixlen = IPV6_MAX_BITLEN;
548 }
549 else
550 {
551 int plen;
552
553 cp = XMALLOC (0, (pnt - str) + 1);
554 strncpy (cp, str, pnt - str);
555 *(cp + (pnt - str)) = '\0';
556 ret = inet_pton (AF_INET6, cp, &p->prefix);
557 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100558 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000559 return 0;
560 plen = (u_char) atoi (++pnt);
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400561 if (plen > IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000562 return 0;
563 p->prefixlen = plen;
564 }
565 p->family = AF_INET6;
566
567 return ret;
568}
569
hassob04c6992004-10-04 19:10:31 +0000570/* Convert struct in6_addr netmask into integer.
571 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000572int
573ip6_masklen (struct in6_addr netmask)
574{
575 int len = 0;
576 unsigned char val;
577 unsigned char *pnt;
578
579 pnt = (unsigned char *) & netmask;
580
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400581 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000582 {
583 len += 8;
584 pnt++;
585 }
586
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400587 if (len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000588 {
589 val = *pnt;
590 while (val)
591 {
592 len++;
593 val <<= 1;
594 }
595 }
596 return len;
597}
598
599void
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400600masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000601{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400602 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400603 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000604}
605
606void
607apply_mask_ipv6 (struct prefix_ipv6 *p)
608{
Denis Ovsienko8c7f49d2012-01-01 16:33:12 +0400609 u_char *pnt;
610 int index;
611 int offset;
612
613 index = p->prefixlen / 8;
614
615 if (index < 16)
616 {
617 pnt = (u_char *) &p->prefix;
618 offset = p->prefixlen % 8;
619
620 pnt[index] &= maskbit[offset];
621 index++;
622
623 while (index < 16)
624 pnt[index++] = 0;
625 }
paul718e3742002-12-13 20:15:29 +0000626}
627
628void
hassob04c6992004-10-04 19:10:31 +0000629str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000630{
631 int i;
632 unsigned int x;
633
634 /* %x must point to unsinged int */
635 for (i = 0; i < 16; i++)
636 {
637 sscanf (str + (i * 2), "%02x", &x);
638 addr->s6_addr[i] = x & 0xff;
639 }
640}
641#endif /* HAVE_IPV6 */
642
643void
644apply_mask (struct prefix *p)
645{
646 switch (p->family)
647 {
648 case AF_INET:
649 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
650 break;
651#ifdef HAVE_IPV6
652 case AF_INET6:
653 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
654 break;
655#endif /* HAVE_IPV6 */
656 default:
657 break;
658 }
659 return;
660}
661
hassob04c6992004-10-04 19:10:31 +0000662/* Utility function of convert between struct prefix <=> union sockunion.
663 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000664struct prefix *
hassob04c6992004-10-04 19:10:31 +0000665sockunion2prefix (const union sockunion *dest,
666 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000667{
668 if (dest->sa.sa_family == AF_INET)
669 {
670 struct prefix_ipv4 *p;
671
672 p = prefix_ipv4_new ();
673 p->family = AF_INET;
674 p->prefix = dest->sin.sin_addr;
675 p->prefixlen = ip_masklen (mask->sin.sin_addr);
676 return (struct prefix *) p;
677 }
678#ifdef HAVE_IPV6
679 if (dest->sa.sa_family == AF_INET6)
680 {
681 struct prefix_ipv6 *p;
682
683 p = prefix_ipv6_new ();
684 p->family = AF_INET6;
685 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
686 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
687 return (struct prefix *) p;
688 }
689#endif /* HAVE_IPV6 */
690 return NULL;
691}
692
hassob04c6992004-10-04 19:10:31 +0000693/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000694struct prefix *
Timo Teräsc1c69e42015-05-22 13:40:57 +0300695sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
paul718e3742002-12-13 20:15:29 +0000696{
697 if (su->sa.sa_family == AF_INET)
698 {
699 struct prefix_ipv4 *p;
700
Timo Teräsc1c69e42015-05-22 13:40:57 +0300701 p = prefix ? (struct prefix_ipv4 *) prefix : prefix_ipv4_new ();
paul718e3742002-12-13 20:15:29 +0000702 p->family = AF_INET;
703 p->prefix = su->sin.sin_addr;
704 p->prefixlen = IPV4_MAX_BITLEN;
705 return (struct prefix *) p;
706 }
707#ifdef HAVE_IPV6
708 if (su->sa.sa_family == AF_INET6)
709 {
710 struct prefix_ipv6 *p;
711
Timo Teräsc1c69e42015-05-22 13:40:57 +0300712 p = prefix ? (struct prefix_ipv6 *) prefix : prefix_ipv6_new ();
paul718e3742002-12-13 20:15:29 +0000713 p->family = AF_INET6;
714 p->prefixlen = IPV6_MAX_BITLEN;
715 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
716 return (struct prefix *) p;
717 }
718#endif /* HAVE_IPV6 */
719 return NULL;
720}
721
David Lamparter17e52062010-02-02 20:16:35 +0100722void
723prefix2sockunion (const struct prefix *p, union sockunion *su)
724{
725 memset (su, 0, sizeof (*su));
726
727 su->sa.sa_family = p->family;
728 if (p->family == AF_INET)
729 su->sin.sin_addr = p->u.prefix4;
730#ifdef HAVE_IPV6
731 if (p->family == AF_INET6)
732 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
733#endif /* HAVE_IPV6 */
734}
735
paul718e3742002-12-13 20:15:29 +0000736int
hassob04c6992004-10-04 19:10:31 +0000737prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000738{
739 switch (p->family)
740 {
741 case AF_INET:
742 return IPV4_MAX_BYTELEN;
743 break;
744#ifdef HAVE_IPV6
745 case AF_INET6:
746 return IPV6_MAX_BYTELEN;
747 break;
748#endif /* HAVE_IPV6 */
749 }
750 return 0;
751}
752
753/* Generic function for conversion string to struct prefix. */
754int
hassob04c6992004-10-04 19:10:31 +0000755str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000756{
757 int ret;
758
759 /* First we try to convert string to struct prefix_ipv4. */
760 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
761 if (ret)
762 return ret;
763
764#ifdef HAVE_IPV6
765 /* Next we try to convert string to struct prefix_ipv6. */
766 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
767 if (ret)
768 return ret;
769#endif /* HAVE_IPV6 */
770
771 return 0;
772}
773
Timo Teräs41eb9a42015-05-23 11:08:39 +0300774const char *
775prefix2str (union prefix46constptr pu, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000776{
Timo Teräs41eb9a42015-05-23 11:08:39 +0300777 const struct prefix *p = pu.p;
paul718e3742002-12-13 20:15:29 +0000778 char buf[BUFSIZ];
779
780 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
781 snprintf (str, size, "%s/%d", buf, p->prefixlen);
Timo Teräs41eb9a42015-05-23 11:08:39 +0300782 return str;
paul718e3742002-12-13 20:15:29 +0000783}
784
785struct prefix *
786prefix_new ()
787{
788 struct prefix *p;
789
790 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
791 return p;
792}
793
794/* Free prefix structure. */
795void
796prefix_free (struct prefix *p)
797{
798 XFREE (MTYPE_PREFIX, p);
799}
800
801/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000802 * character.
803 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000804int
hassob04c6992004-10-04 19:10:31 +0000805all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000806{
807 for (; *str != '\0'; str++)
808 if (!isdigit ((int) *str))
809 return 0;
810 return 1;
811}
812
813/* Utility function to convert ipv4 prefixes to Classful prefixes */
814void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
815{
816
817 u_int32_t destination;
818
819 destination = ntohl (p->prefix.s_addr);
820
hasso3fb9cd62004-10-19 19:44:43 +0000821 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000822 /* do nothing for host routes */
823 else if (IN_CLASSC (destination))
824 {
825 p->prefixlen=24;
826 apply_mask_ipv4(p);
827 }
828 else if (IN_CLASSB(destination))
829 {
830 p->prefixlen=16;
831 apply_mask_ipv4(p);
832 }
833 else
834 {
835 p->prefixlen=8;
836 apply_mask_ipv4(p);
837 }
838}
839
hasso3fb9cd62004-10-19 19:44:43 +0000840in_addr_t
841ipv4_network_addr (in_addr_t hostaddr, int masklen)
842{
843 struct in_addr mask;
844
845 masklen2ip (masklen, &mask);
846 return hostaddr & mask.s_addr;
847}
848
849in_addr_t
850ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
851{
852 struct in_addr mask;
853
854 masklen2ip (masklen, &mask);
855 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
856 /* normal case */
857 (hostaddr | ~mask.s_addr) :
858 /* special case for /31 */
859 (hostaddr ^ ~mask.s_addr);
860}
861
paul718e3742002-12-13 20:15:29 +0000862/* Utility function to convert ipv4 netmask to prefixes
863 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
864 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
865int
hassob04c6992004-10-04 19:10:31 +0000866netmask_str2prefix_str (const char *net_str, const char *mask_str,
867 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000868{
869 struct in_addr network;
870 struct in_addr mask;
871 u_char prefixlen;
872 u_int32_t destination;
873 int ret;
874
875 ret = inet_aton (net_str, &network);
876 if (! ret)
877 return 0;
878
879 if (mask_str)
880 {
881 ret = inet_aton (mask_str, &mask);
882 if (! ret)
883 return 0;
884
885 prefixlen = ip_masklen (mask);
886 }
887 else
888 {
889 destination = ntohl (network.s_addr);
890
891 if (network.s_addr == 0)
892 prefixlen = 0;
893 else if (IN_CLASSC (destination))
894 prefixlen = 24;
895 else if (IN_CLASSB (destination))
896 prefixlen = 16;
897 else if (IN_CLASSA (destination))
898 prefixlen = 8;
899 else
900 return 0;
901 }
902
903 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
904
905 return 1;
906}
907
hasso59209902005-04-05 14:36:49 +0000908#ifdef HAVE_IPV6
909/* Utility function for making IPv6 address string. */
910const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000911inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000912{
913 static char buf[INET6_ADDRSTRLEN];
914
hasso3a2ce6a2005-04-08 01:30:51 +0000915 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000916 return buf;
917}
918#endif /* HAVE_IPV6 */