blob: 3e4ca16791deeff39b03c54f8d8c95d1c4af7c91 [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
Lou Berger2daf7f32016-01-12 13:41:50 -0500226const char *
227safi2str(safi_t safi)
228{
229 switch (safi) {
230 case SAFI_UNICAST:
231 return "unicast";
232 case SAFI_MULTICAST:
233 return "multicast";
234 case SAFI_ENCAP:
235 return "encap";
236 case SAFI_MPLS_VPN:
237 return "vpn";
238 }
239 return NULL;
240}
241
paul718e3742002-12-13 20:15:29 +0000242/* If n includes p prefix then return 1 else return 0. */
243int
hassob04c6992004-10-04 19:10:31 +0000244prefix_match (const struct prefix *n, const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000245{
246 int offset;
247 int shift;
Paul Jakmad3583442010-01-24 21:41:02 +0000248 const u_char *np, *pp;
paul718e3742002-12-13 20:15:29 +0000249
250 /* If n's prefix is longer than p's one return 0. */
251 if (n->prefixlen > p->prefixlen)
252 return 0;
253
Paul Jakmad3583442010-01-24 21:41:02 +0000254 /* Set both prefix's head pointer. */
255 np = (const u_char *)&n->u.prefix;
256 pp = (const u_char *)&p->u.prefix;
257
paul718e3742002-12-13 20:15:29 +0000258 offset = n->prefixlen / PNBBY;
259 shift = n->prefixlen % PNBBY;
260
261 if (shift)
262 if (maskbit[shift] & (np[offset] ^ pp[offset]))
263 return 0;
264
265 while (offset--)
266 if (np[offset] != pp[offset])
267 return 0;
268 return 1;
269}
270
271/* Copy prefix from src to dest. */
272void
hassob04c6992004-10-04 19:10:31 +0000273prefix_copy (struct prefix *dest, const struct prefix *src)
paul718e3742002-12-13 20:15:29 +0000274{
275 dest->family = src->family;
276 dest->prefixlen = src->prefixlen;
277
278 if (src->family == AF_INET)
279 dest->u.prefix4 = src->u.prefix4;
280#ifdef HAVE_IPV6
281 else if (src->family == AF_INET6)
282 dest->u.prefix6 = src->u.prefix6;
283#endif /* HAVE_IPV6 */
284 else if (src->family == AF_UNSPEC)
285 {
286 dest->u.lp.id = src->u.lp.id;
287 dest->u.lp.adv_router = src->u.lp.adv_router;
288 }
289 else
290 {
ajsb9e70282004-12-08 17:14:45 +0000291 zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
paul718e3742002-12-13 20:15:29 +0000292 src->family);
293 assert (0);
294 }
295}
296
gdt9d24baa2004-01-13 14:55:40 +0000297/*
298 * Return 1 if the address/netmask contained in the prefix structure
299 * is the same, and else return 0. For this routine, 'same' requires
300 * that not only the prefix length and the network part be the same,
301 * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
302 * the same. Note that this routine has the same return value sense
303 * as '==' (which is different from prefix_cmp).
304 */
paul718e3742002-12-13 20:15:29 +0000305int
hassob04c6992004-10-04 19:10:31 +0000306prefix_same (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000307{
308 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
309 {
310 if (p1->family == AF_INET)
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400311 if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
paul718e3742002-12-13 20:15:29 +0000312 return 1;
313#ifdef HAVE_IPV6
314 if (p1->family == AF_INET6 )
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400315 if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
paul718e3742002-12-13 20:15:29 +0000316 return 1;
317#endif /* HAVE_IPV6 */
318 }
319 return 0;
320}
321
gdt9d24baa2004-01-13 14:55:40 +0000322/*
323 * Return 0 if the network prefixes represented by the struct prefix
324 * arguments are the same prefix, and 1 otherwise. Network prefixes
325 * are considered the same if the prefix lengths are equal and the
326 * network parts are the same. Host bits (which are considered masked
327 * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
328 * 10.0.0.2/8 are considered equivalent by this routine. Note that
329 * this routine has the same return sense as strcmp (which is different
330 * from prefix_same).
331 */
paul718e3742002-12-13 20:15:29 +0000332int
hassob04c6992004-10-04 19:10:31 +0000333prefix_cmp (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000334{
335 int offset;
336 int shift;
337
338 /* Set both prefix's head pointer. */
paul8cc41982005-05-06 21:25:49 +0000339 const u_char *pp1 = (const u_char *)&p1->u.prefix;
340 const u_char *pp2 = (const u_char *)&p2->u.prefix;
paul718e3742002-12-13 20:15:29 +0000341
342 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
343 return 1;
344
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400345 offset = p1->prefixlen / PNBBY;
346 shift = p1->prefixlen % PNBBY;
paul718e3742002-12-13 20:15:29 +0000347
348 if (shift)
349 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
350 return 1;
351
352 while (offset--)
353 if (pp1[offset] != pp2[offset])
354 return 1;
355
356 return 0;
357}
358
David Lamparter17e52062010-02-02 20:16:35 +0100359/*
360 * Count the number of common bits in 2 prefixes. The prefix length is
361 * ignored for this function; the whole prefix is compared. If the prefix
362 * address families don't match, return -1; otherwise the return value is
363 * in range 0 ... maximum prefix length for the address family.
364 */
365int
366prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
367{
368 int pos, bit;
369 int length = 0;
370 u_char xor;
371
372 /* Set both prefix's head pointer. */
373 const u_char *pp1 = (const u_char *)&p1->u.prefix;
374 const u_char *pp2 = (const u_char *)&p2->u.prefix;
375
376 if (p1->family == AF_INET)
377 length = IPV4_MAX_BYTELEN;
378#ifdef HAVE_IPV6
379 if (p1->family == AF_INET6)
380 length = IPV6_MAX_BYTELEN;
381#endif
382 if (p1->family != p2->family || !length)
383 return -1;
384
385 for (pos = 0; pos < length; pos++)
386 if (pp1[pos] != pp2[pos])
387 break;
388 if (pos == length)
389 return pos * 8;
390
391 xor = pp1[pos] ^ pp2[pos];
392 for (bit = 0; bit < 8; bit++)
393 if (xor & (1 << (7 - bit)))
394 break;
395
396 return pos * 8 + bit;
397}
398
paul718e3742002-12-13 20:15:29 +0000399/* Return prefix family type string. */
hassob04c6992004-10-04 19:10:31 +0000400const char *
401prefix_family_str (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000402{
403 if (p->family == AF_INET)
404 return "inet";
405#ifdef HAVE_IPV6
406 if (p->family == AF_INET6)
407 return "inet6";
408#endif /* HAVE_IPV6 */
409 return "unspec";
410}
411
412/* Allocate new prefix_ipv4 structure. */
413struct prefix_ipv4 *
414prefix_ipv4_new ()
415{
416 struct prefix_ipv4 *p;
417
ajs7907c6c2005-07-26 19:55:31 +0000418 /* Call prefix_new to allocate a full-size struct prefix to avoid problems
419 where the struct prefix_ipv4 is cast to struct prefix and unallocated
420 bytes were being referenced (e.g. in structure assignments). */
421 p = (struct prefix_ipv4 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000422 p->family = AF_INET;
423 return p;
424}
425
426/* Free prefix_ipv4 structure. */
427void
428prefix_ipv4_free (struct prefix_ipv4 *p)
429{
ajs7907c6c2005-07-26 19:55:31 +0000430 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000431}
432
433/* When string format is invalid return 0. */
434int
hassob04c6992004-10-04 19:10:31 +0000435str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000436{
437 int ret;
438 int plen;
439 char *pnt;
440 char *cp;
441
442 /* Find slash inside string. */
443 pnt = strchr (str, '/');
444
445 /* String doesn't contail slash. */
446 if (pnt == NULL)
447 {
448 /* Convert string to prefix. */
449 ret = inet_aton (str, &p->prefix);
450 if (ret == 0)
451 return 0;
452
453 /* If address doesn't contain slash we assume it host address. */
454 p->family = AF_INET;
455 p->prefixlen = IPV4_MAX_BITLEN;
456
457 return ret;
458 }
459 else
460 {
461 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
462 strncpy (cp, str, pnt - str);
463 *(cp + (pnt - str)) = '\0';
464 ret = inet_aton (cp, &p->prefix);
465 XFREE (MTYPE_TMP, cp);
466
467 /* Get prefix length. */
468 plen = (u_char) atoi (++pnt);
hasso3fb9cd62004-10-19 19:44:43 +0000469 if (plen > IPV4_MAX_PREFIXLEN)
paul718e3742002-12-13 20:15:29 +0000470 return 0;
471
472 p->family = AF_INET;
473 p->prefixlen = plen;
474 }
475
476 return ret;
477}
478
Denis Ovsienko051954f2011-10-11 15:17:45 +0400479/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000480void
Denis Ovsienko96633862011-10-08 18:15:21 +0400481masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000482{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400483 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
David Lampartere96b3122012-04-04 00:14:36 +0200484
485 /* left shift is only defined for less than the size of the type.
486 * we unconditionally use long long in case the target platform
487 * has defined behaviour for << 32 (or has a 64-bit left shift) */
488
489 if (sizeof(unsigned long long) > 4)
490 netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
491 else
492 netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
paul718e3742002-12-13 20:15:29 +0000493}
494
495/* Convert IP address's netmask into integer. We assume netmask is
496 sequential one. Argument netmask should be network byte order. */
497u_char
498ip_masklen (struct in_addr netmask)
499{
David Lampartere96b3122012-04-04 00:14:36 +0200500 uint32_t tmp = ~ntohl(netmask.s_addr);
501 if (tmp)
502 /* clz: count leading zeroes. sadly, the behaviour of this builtin
503 * is undefined for a 0 argument, even though most CPUs give 32 */
504 return __builtin_clz(tmp);
505 else
506 return 32;
paul718e3742002-12-13 20:15:29 +0000507}
508
Denis Ovsienkocaff7902011-10-18 18:33:53 +0400509/* Apply mask to IPv4 prefix (network byte order). */
paul718e3742002-12-13 20:15:29 +0000510void
511apply_mask_ipv4 (struct prefix_ipv4 *p)
512{
David Lampartere96b3122012-04-04 00:14:36 +0200513 struct in_addr mask;
514 masklen2ip(p->prefixlen, &mask);
515 p->prefix.s_addr &= mask.s_addr;
paul718e3742002-12-13 20:15:29 +0000516}
517
518/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
519int
hassob04c6992004-10-04 19:10:31 +0000520prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000521{
522 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
523}
David Lamparter6b0655a2014-06-04 06:53:35 +0200524
paul718e3742002-12-13 20:15:29 +0000525#ifdef HAVE_IPV6
526
527/* Allocate a new ip version 6 route */
528struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000529prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000530{
531 struct prefix_ipv6 *p;
532
ajs7907c6c2005-07-26 19:55:31 +0000533 /* Allocate a full-size struct prefix to avoid problems with structure
534 size mismatches. */
535 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000536 p->family = AF_INET6;
537 return p;
538}
539
540/* Free prefix for IPv6. */
541void
542prefix_ipv6_free (struct prefix_ipv6 *p)
543{
ajs7907c6c2005-07-26 19:55:31 +0000544 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000545}
546
547/* If given string is valid return pin6 else return NULL */
548int
hassob04c6992004-10-04 19:10:31 +0000549str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000550{
551 char *pnt;
552 char *cp;
553 int ret;
554
555 pnt = strchr (str, '/');
556
557 /* If string doesn't contain `/' treat it as host route. */
558 if (pnt == NULL)
559 {
560 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100561 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000562 return 0;
563 p->prefixlen = IPV6_MAX_BITLEN;
564 }
565 else
566 {
567 int plen;
568
569 cp = XMALLOC (0, (pnt - str) + 1);
570 strncpy (cp, str, pnt - str);
571 *(cp + (pnt - str)) = '\0';
572 ret = inet_pton (AF_INET6, cp, &p->prefix);
573 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100574 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000575 return 0;
576 plen = (u_char) atoi (++pnt);
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400577 if (plen > IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000578 return 0;
579 p->prefixlen = plen;
580 }
581 p->family = AF_INET6;
582
583 return ret;
584}
585
hassob04c6992004-10-04 19:10:31 +0000586/* Convert struct in6_addr netmask into integer.
587 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000588int
589ip6_masklen (struct in6_addr netmask)
590{
591 int len = 0;
592 unsigned char val;
593 unsigned char *pnt;
594
595 pnt = (unsigned char *) & netmask;
596
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400597 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000598 {
599 len += 8;
600 pnt++;
601 }
602
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400603 if (len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000604 {
605 val = *pnt;
606 while (val)
607 {
608 len++;
609 val <<= 1;
610 }
611 }
612 return len;
613}
614
615void
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400616masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000617{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400618 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400619 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000620}
621
622void
623apply_mask_ipv6 (struct prefix_ipv6 *p)
624{
Denis Ovsienko8c7f49d2012-01-01 16:33:12 +0400625 u_char *pnt;
626 int index;
627 int offset;
628
629 index = p->prefixlen / 8;
630
631 if (index < 16)
632 {
633 pnt = (u_char *) &p->prefix;
634 offset = p->prefixlen % 8;
635
636 pnt[index] &= maskbit[offset];
637 index++;
638
639 while (index < 16)
640 pnt[index++] = 0;
641 }
paul718e3742002-12-13 20:15:29 +0000642}
643
644void
hassob04c6992004-10-04 19:10:31 +0000645str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000646{
647 int i;
648 unsigned int x;
649
650 /* %x must point to unsinged int */
651 for (i = 0; i < 16; i++)
652 {
653 sscanf (str + (i * 2), "%02x", &x);
654 addr->s6_addr[i] = x & 0xff;
655 }
656}
657#endif /* HAVE_IPV6 */
658
659void
660apply_mask (struct prefix *p)
661{
662 switch (p->family)
663 {
664 case AF_INET:
665 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
666 break;
667#ifdef HAVE_IPV6
668 case AF_INET6:
669 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
670 break;
671#endif /* HAVE_IPV6 */
672 default:
673 break;
674 }
675 return;
676}
677
hassob04c6992004-10-04 19:10:31 +0000678/* Utility function of convert between struct prefix <=> union sockunion.
679 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000680struct prefix *
hassob04c6992004-10-04 19:10:31 +0000681sockunion2prefix (const union sockunion *dest,
682 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000683{
684 if (dest->sa.sa_family == AF_INET)
685 {
686 struct prefix_ipv4 *p;
687
688 p = prefix_ipv4_new ();
689 p->family = AF_INET;
690 p->prefix = dest->sin.sin_addr;
691 p->prefixlen = ip_masklen (mask->sin.sin_addr);
692 return (struct prefix *) p;
693 }
694#ifdef HAVE_IPV6
695 if (dest->sa.sa_family == AF_INET6)
696 {
697 struct prefix_ipv6 *p;
698
699 p = prefix_ipv6_new ();
700 p->family = AF_INET6;
701 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
702 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
703 return (struct prefix *) p;
704 }
705#endif /* HAVE_IPV6 */
706 return NULL;
707}
708
hassob04c6992004-10-04 19:10:31 +0000709/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000710struct prefix *
Timo Teräsc1c69e42015-05-22 13:40:57 +0300711sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
paul718e3742002-12-13 20:15:29 +0000712{
713 if (su->sa.sa_family == AF_INET)
714 {
715 struct prefix_ipv4 *p;
716
Timo Teräsc1c69e42015-05-22 13:40:57 +0300717 p = prefix ? (struct prefix_ipv4 *) prefix : prefix_ipv4_new ();
paul718e3742002-12-13 20:15:29 +0000718 p->family = AF_INET;
719 p->prefix = su->sin.sin_addr;
720 p->prefixlen = IPV4_MAX_BITLEN;
721 return (struct prefix *) p;
722 }
723#ifdef HAVE_IPV6
724 if (su->sa.sa_family == AF_INET6)
725 {
726 struct prefix_ipv6 *p;
727
Timo Teräsc1c69e42015-05-22 13:40:57 +0300728 p = prefix ? (struct prefix_ipv6 *) prefix : prefix_ipv6_new ();
paul718e3742002-12-13 20:15:29 +0000729 p->family = AF_INET6;
730 p->prefixlen = IPV6_MAX_BITLEN;
731 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
732 return (struct prefix *) p;
733 }
734#endif /* HAVE_IPV6 */
735 return NULL;
736}
737
David Lamparter17e52062010-02-02 20:16:35 +0100738void
739prefix2sockunion (const struct prefix *p, union sockunion *su)
740{
741 memset (su, 0, sizeof (*su));
742
743 su->sa.sa_family = p->family;
744 if (p->family == AF_INET)
745 su->sin.sin_addr = p->u.prefix4;
746#ifdef HAVE_IPV6
747 if (p->family == AF_INET6)
748 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
749#endif /* HAVE_IPV6 */
750}
751
paul718e3742002-12-13 20:15:29 +0000752int
hassob04c6992004-10-04 19:10:31 +0000753prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000754{
755 switch (p->family)
756 {
757 case AF_INET:
758 return IPV4_MAX_BYTELEN;
759 break;
760#ifdef HAVE_IPV6
761 case AF_INET6:
762 return IPV6_MAX_BYTELEN;
763 break;
764#endif /* HAVE_IPV6 */
765 }
766 return 0;
767}
768
769/* Generic function for conversion string to struct prefix. */
770int
hassob04c6992004-10-04 19:10:31 +0000771str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000772{
773 int ret;
774
775 /* First we try to convert string to struct prefix_ipv4. */
776 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
777 if (ret)
778 return ret;
779
780#ifdef HAVE_IPV6
781 /* Next we try to convert string to struct prefix_ipv6. */
782 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
783 if (ret)
784 return ret;
785#endif /* HAVE_IPV6 */
786
787 return 0;
788}
789
Timo Teräs41eb9a42015-05-23 11:08:39 +0300790const char *
791prefix2str (union prefix46constptr pu, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000792{
Timo Teräs41eb9a42015-05-23 11:08:39 +0300793 const struct prefix *p = pu.p;
paul718e3742002-12-13 20:15:29 +0000794 char buf[BUFSIZ];
795
796 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
797 snprintf (str, size, "%s/%d", buf, p->prefixlen);
Timo Teräs41eb9a42015-05-23 11:08:39 +0300798 return str;
paul718e3742002-12-13 20:15:29 +0000799}
800
801struct prefix *
802prefix_new ()
803{
804 struct prefix *p;
805
806 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
807 return p;
808}
809
810/* Free prefix structure. */
811void
812prefix_free (struct prefix *p)
813{
814 XFREE (MTYPE_PREFIX, p);
815}
816
817/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000818 * character.
819 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000820int
hassob04c6992004-10-04 19:10:31 +0000821all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000822{
823 for (; *str != '\0'; str++)
824 if (!isdigit ((int) *str))
825 return 0;
826 return 1;
827}
828
829/* Utility function to convert ipv4 prefixes to Classful prefixes */
830void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
831{
832
833 u_int32_t destination;
834
835 destination = ntohl (p->prefix.s_addr);
836
hasso3fb9cd62004-10-19 19:44:43 +0000837 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000838 /* do nothing for host routes */
839 else if (IN_CLASSC (destination))
840 {
841 p->prefixlen=24;
842 apply_mask_ipv4(p);
843 }
844 else if (IN_CLASSB(destination))
845 {
846 p->prefixlen=16;
847 apply_mask_ipv4(p);
848 }
849 else
850 {
851 p->prefixlen=8;
852 apply_mask_ipv4(p);
853 }
854}
855
hasso3fb9cd62004-10-19 19:44:43 +0000856in_addr_t
857ipv4_network_addr (in_addr_t hostaddr, int masklen)
858{
859 struct in_addr mask;
860
861 masklen2ip (masklen, &mask);
862 return hostaddr & mask.s_addr;
863}
864
865in_addr_t
866ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
867{
868 struct in_addr mask;
869
870 masklen2ip (masklen, &mask);
871 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
872 /* normal case */
873 (hostaddr | ~mask.s_addr) :
874 /* special case for /31 */
875 (hostaddr ^ ~mask.s_addr);
876}
877
paul718e3742002-12-13 20:15:29 +0000878/* Utility function to convert ipv4 netmask to prefixes
879 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
880 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
881int
hassob04c6992004-10-04 19:10:31 +0000882netmask_str2prefix_str (const char *net_str, const char *mask_str,
883 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000884{
885 struct in_addr network;
886 struct in_addr mask;
887 u_char prefixlen;
888 u_int32_t destination;
889 int ret;
890
891 ret = inet_aton (net_str, &network);
892 if (! ret)
893 return 0;
894
895 if (mask_str)
896 {
897 ret = inet_aton (mask_str, &mask);
898 if (! ret)
899 return 0;
900
901 prefixlen = ip_masklen (mask);
902 }
903 else
904 {
905 destination = ntohl (network.s_addr);
906
907 if (network.s_addr == 0)
908 prefixlen = 0;
909 else if (IN_CLASSC (destination))
910 prefixlen = 24;
911 else if (IN_CLASSB (destination))
912 prefixlen = 16;
913 else if (IN_CLASSA (destination))
914 prefixlen = 8;
915 else
916 return 0;
917 }
918
919 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
920
921 return 1;
922}
923
hasso59209902005-04-05 14:36:49 +0000924#ifdef HAVE_IPV6
925/* Utility function for making IPv6 address string. */
926const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000927inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000928{
929 static char buf[INET6_ADDRSTRLEN];
930
hasso3a2ce6a2005-04-08 01:30:51 +0000931 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000932 return buf;
933}
934#endif /* HAVE_IPV6 */