Line data Source code
1 : /*
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. */
32 : static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
33 : 0xf8, 0xfc, 0xfe, 0xff};
34 :
35 : static 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 : };
167 :
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 :
175 : unsigned int
176 1091070 : prefix_bit (const u_char *prefix, const u_char prefixlen)
177 : {
178 1091070 : unsigned int offset = prefixlen / 8;
179 1091070 : unsigned int shift = 7 - (prefixlen % 8);
180 :
181 1091070 : return (prefix[offset] >> shift) & 1;
182 : }
183 :
184 : unsigned int
185 0 : prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
186 : {
187 0 : return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
188 : }
189 :
190 : /* Address Famiy Identifier to Address Family converter. */
191 : int
192 0 : afi2family (afi_t afi)
193 : {
194 0 : if (afi == AFI_IP)
195 0 : return AF_INET;
196 : #ifdef HAVE_IPV6
197 0 : else if (afi == AFI_IP6)
198 0 : return AF_INET6;
199 : #endif /* HAVE_IPV6 */
200 0 : return 0;
201 : }
202 :
203 : afi_t
204 0 : family2afi (int family)
205 : {
206 0 : if (family == AF_INET)
207 0 : return AFI_IP;
208 : #ifdef HAVE_IPV6
209 0 : else if (family == AF_INET6)
210 0 : return AFI_IP6;
211 : #endif /* HAVE_IPV6 */
212 0 : return 0;
213 : }
214 :
215 : /* If n includes p prefix then return 1 else return 0. */
216 : int
217 1332918 : prefix_match (const struct prefix *n, const struct prefix *p)
218 : {
219 : int offset;
220 : int shift;
221 : const u_char *np, *pp;
222 :
223 : /* If n's prefix is longer than p's one return 0. */
224 1332918 : if (n->prefixlen > p->prefixlen)
225 0 : return 0;
226 :
227 : /* Set both prefix's head pointer. */
228 1332918 : np = (const u_char *)&n->u.prefix;
229 1332918 : pp = (const u_char *)&p->u.prefix;
230 :
231 1332918 : offset = n->prefixlen / PNBBY;
232 1332918 : shift = n->prefixlen % PNBBY;
233 :
234 1332918 : if (shift)
235 1094670 : if (maskbit[shift] & (np[offset] ^ pp[offset]))
236 418 : return 0;
237 :
238 4670508 : while (offset--)
239 2005784 : if (np[offset] != pp[offset])
240 276 : return 0;
241 1332224 : return 1;
242 : }
243 :
244 : /* Copy prefix from src to dest. */
245 : void
246 1500 : prefix_copy (struct prefix *dest, const struct prefix *src)
247 : {
248 1500 : dest->family = src->family;
249 1500 : dest->prefixlen = src->prefixlen;
250 :
251 1500 : if (src->family == AF_INET)
252 437 : dest->u.prefix4 = src->u.prefix4;
253 : #ifdef HAVE_IPV6
254 1063 : else if (src->family == AF_INET6)
255 1063 : dest->u.prefix6 = src->u.prefix6;
256 : #endif /* HAVE_IPV6 */
257 0 : else if (src->family == AF_UNSPEC)
258 : {
259 0 : dest->u.lp.id = src->u.lp.id;
260 0 : dest->u.lp.adv_router = src->u.lp.adv_router;
261 : }
262 : else
263 : {
264 0 : zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
265 0 : src->family);
266 0 : assert (0);
267 : }
268 1500 : }
269 :
270 : /*
271 : * Return 1 if the address/netmask contained in the prefix structure
272 : * is the same, and else return 0. For this routine, 'same' requires
273 : * that not only the prefix length and the network part be the same,
274 : * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
275 : * the same. Note that this routine has the same return value sense
276 : * as '==' (which is different from prefix_cmp).
277 : */
278 : int
279 283 : prefix_same (const struct prefix *p1, const struct prefix *p2)
280 : {
281 283 : if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
282 : {
283 145 : if (p1->family == AF_INET)
284 98 : if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
285 10 : return 1;
286 : #ifdef HAVE_IPV6
287 135 : if (p1->family == AF_INET6 )
288 47 : if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
289 7 : return 1;
290 : #endif /* HAVE_IPV6 */
291 : }
292 266 : return 0;
293 : }
294 :
295 : /*
296 : * Return 0 if the network prefixes represented by the struct prefix
297 : * arguments are the same prefix, and 1 otherwise. Network prefixes
298 : * are considered the same if the prefix lengths are equal and the
299 : * network parts are the same. Host bits (which are considered masked
300 : * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
301 : * 10.0.0.2/8 are considered equivalent by this routine. Note that
302 : * this routine has the same return sense as strcmp (which is different
303 : * from prefix_same).
304 : */
305 : int
306 18 : prefix_cmp (const struct prefix *p1, const struct prefix *p2)
307 : {
308 : int offset;
309 : int shift;
310 :
311 : /* Set both prefix's head pointer. */
312 18 : const u_char *pp1 = (const u_char *)&p1->u.prefix;
313 18 : const u_char *pp2 = (const u_char *)&p2->u.prefix;
314 :
315 18 : if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
316 0 : return 1;
317 :
318 18 : offset = p1->prefixlen / PNBBY;
319 18 : shift = p1->prefixlen % PNBBY;
320 :
321 18 : if (shift)
322 14 : if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
323 0 : return 1;
324 :
325 82 : while (offset--)
326 46 : if (pp1[offset] != pp2[offset])
327 0 : return 1;
328 :
329 18 : return 0;
330 : }
331 :
332 : /*
333 : * Count the number of common bits in 2 prefixes. The prefix length is
334 : * ignored for this function; the whole prefix is compared. If the prefix
335 : * address families don't match, return -1; otherwise the return value is
336 : * in range 0 ... maximum prefix length for the address family.
337 : */
338 : int
339 0 : prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
340 : {
341 : int pos, bit;
342 0 : int length = 0;
343 : u_char xor;
344 :
345 : /* Set both prefix's head pointer. */
346 0 : const u_char *pp1 = (const u_char *)&p1->u.prefix;
347 0 : const u_char *pp2 = (const u_char *)&p2->u.prefix;
348 :
349 0 : if (p1->family == AF_INET)
350 0 : length = IPV4_MAX_BYTELEN;
351 : #ifdef HAVE_IPV6
352 0 : if (p1->family == AF_INET6)
353 0 : length = IPV6_MAX_BYTELEN;
354 : #endif
355 0 : if (p1->family != p2->family || !length)
356 0 : return -1;
357 :
358 0 : for (pos = 0; pos < length; pos++)
359 0 : if (pp1[pos] != pp2[pos])
360 0 : break;
361 0 : if (pos == length)
362 0 : return pos * 8;
363 :
364 0 : xor = pp1[pos] ^ pp2[pos];
365 0 : for (bit = 0; bit < 8; bit++)
366 0 : if (xor & (1 << (7 - bit)))
367 0 : break;
368 :
369 0 : return pos * 8 + bit;
370 : }
371 :
372 : /* Return prefix family type string. */
373 : const char *
374 12 : prefix_family_str (const struct prefix *p)
375 : {
376 12 : if (p->family == AF_INET)
377 6 : return "inet";
378 : #ifdef HAVE_IPV6
379 6 : if (p->family == AF_INET6)
380 6 : return "inet6";
381 : #endif /* HAVE_IPV6 */
382 0 : return "unspec";
383 : }
384 :
385 : /* Allocate new prefix_ipv4 structure. */
386 : struct prefix_ipv4 *
387 112 : prefix_ipv4_new ()
388 : {
389 : struct prefix_ipv4 *p;
390 :
391 : /* Call prefix_new to allocate a full-size struct prefix to avoid problems
392 : where the struct prefix_ipv4 is cast to struct prefix and unallocated
393 : bytes were being referenced (e.g. in structure assignments). */
394 112 : p = (struct prefix_ipv4 *)prefix_new();
395 112 : p->family = AF_INET;
396 112 : return p;
397 : }
398 :
399 : /* Free prefix_ipv4 structure. */
400 : void
401 0 : prefix_ipv4_free (struct prefix_ipv4 *p)
402 : {
403 0 : prefix_free((struct prefix *)p);
404 0 : }
405 :
406 : /* When string format is invalid return 0. */
407 : int
408 68 : str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
409 : {
410 : int ret;
411 : int plen;
412 : char *pnt;
413 : char *cp;
414 :
415 : /* Find slash inside string. */
416 68 : pnt = strchr (str, '/');
417 :
418 : /* String doesn't contail slash. */
419 68 : if (pnt == NULL)
420 : {
421 : /* Convert string to prefix. */
422 0 : ret = inet_aton (str, &p->prefix);
423 0 : if (ret == 0)
424 0 : return 0;
425 :
426 : /* If address doesn't contain slash we assume it host address. */
427 0 : p->family = AF_INET;
428 0 : p->prefixlen = IPV4_MAX_BITLEN;
429 :
430 0 : return ret;
431 : }
432 : else
433 : {
434 68 : cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
435 68 : strncpy (cp, str, pnt - str);
436 68 : *(cp + (pnt - str)) = '\0';
437 68 : ret = inet_aton (cp, &p->prefix);
438 68 : XFREE (MTYPE_TMP, cp);
439 :
440 : /* Get prefix length. */
441 68 : plen = (u_char) atoi (++pnt);
442 68 : if (plen > IPV4_MAX_PREFIXLEN)
443 0 : return 0;
444 :
445 68 : p->family = AF_INET;
446 68 : p->prefixlen = plen;
447 : }
448 :
449 68 : return ret;
450 : }
451 :
452 : /* Convert masklen into IP address's netmask (network byte order). */
453 : void
454 553 : masklen2ip (const int masklen, struct in_addr *netmask)
455 : {
456 553 : assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
457 :
458 : /* left shift is only defined for less than the size of the type.
459 : * we unconditionally use long long in case the target platform
460 : * has defined behaviour for << 32 (or has a 64-bit left shift) */
461 :
462 : if (sizeof(unsigned long long) > 4)
463 553 : netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
464 : else
465 : netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
466 553 : }
467 :
468 : /* Convert IP address's netmask into integer. We assume netmask is
469 : sequential one. Argument netmask should be network byte order. */
470 : u_char
471 0 : ip_masklen (struct in_addr netmask)
472 : {
473 0 : uint32_t tmp = ~ntohl(netmask.s_addr);
474 0 : if (tmp)
475 : /* clz: count leading zeroes. sadly, the behaviour of this builtin
476 : * is undefined for a 0 argument, even though most CPUs give 32 */
477 0 : return __builtin_clz(tmp);
478 : else
479 0 : return 32;
480 : }
481 :
482 : /* Apply mask to IPv4 prefix (network byte order). */
483 : void
484 551 : apply_mask_ipv4 (struct prefix_ipv4 *p)
485 : {
486 : struct in_addr mask;
487 551 : masklen2ip(p->prefixlen, &mask);
488 551 : p->prefix.s_addr &= mask.s_addr;
489 551 : }
490 :
491 : /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
492 : int
493 115 : prefix_ipv4_any (const struct prefix_ipv4 *p)
494 : {
495 115 : return (p->prefix.s_addr == 0 && p->prefixlen == 0);
496 : }
497 :
498 : #ifdef HAVE_IPV6
499 :
500 : /* Allocate a new ip version 6 route */
501 : struct prefix_ipv6 *
502 171 : prefix_ipv6_new (void)
503 : {
504 : struct prefix_ipv6 *p;
505 :
506 : /* Allocate a full-size struct prefix to avoid problems with structure
507 : size mismatches. */
508 171 : p = (struct prefix_ipv6 *)prefix_new();
509 171 : p->family = AF_INET6;
510 171 : return p;
511 : }
512 :
513 : /* Free prefix for IPv6. */
514 : void
515 0 : prefix_ipv6_free (struct prefix_ipv6 *p)
516 : {
517 0 : prefix_free((struct prefix *)p);
518 0 : }
519 :
520 : /* If given string is valid return pin6 else return NULL */
521 : int
522 1 : str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
523 : {
524 : char *pnt;
525 : char *cp;
526 : int ret;
527 :
528 1 : pnt = strchr (str, '/');
529 :
530 : /* If string doesn't contain `/' treat it as host route. */
531 1 : if (pnt == NULL)
532 : {
533 0 : ret = inet_pton (AF_INET6, str, &p->prefix);
534 0 : if (ret == 0)
535 0 : return 0;
536 0 : p->prefixlen = IPV6_MAX_BITLEN;
537 : }
538 : else
539 : {
540 : int plen;
541 :
542 1 : cp = XMALLOC (0, (pnt - str) + 1);
543 1 : strncpy (cp, str, pnt - str);
544 1 : *(cp + (pnt - str)) = '\0';
545 1 : ret = inet_pton (AF_INET6, cp, &p->prefix);
546 1 : free (cp);
547 1 : if (ret == 0)
548 0 : return 0;
549 1 : plen = (u_char) atoi (++pnt);
550 1 : if (plen > IPV6_MAX_BITLEN)
551 0 : return 0;
552 1 : p->prefixlen = plen;
553 : }
554 1 : p->family = AF_INET6;
555 :
556 1 : return ret;
557 : }
558 :
559 : /* Convert struct in6_addr netmask into integer.
560 : * FIXME return u_char as ip_maskleni() does. */
561 : int
562 0 : ip6_masklen (struct in6_addr netmask)
563 : {
564 0 : int len = 0;
565 : unsigned char val;
566 : unsigned char *pnt;
567 :
568 0 : pnt = (unsigned char *) & netmask;
569 :
570 0 : while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
571 : {
572 0 : len += 8;
573 0 : pnt++;
574 : }
575 :
576 0 : if (len < IPV6_MAX_BITLEN)
577 : {
578 0 : val = *pnt;
579 0 : while (val)
580 : {
581 0 : len++;
582 0 : val <<= 1;
583 : }
584 : }
585 0 : return len;
586 : }
587 :
588 : void
589 0 : masklen2ip6 (const int masklen, struct in6_addr *netmask)
590 : {
591 0 : assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
592 0 : memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
593 0 : }
594 :
595 : void
596 1799 : apply_mask_ipv6 (struct prefix_ipv6 *p)
597 : {
598 : u_char *pnt;
599 : int index;
600 : int offset;
601 :
602 1799 : index = p->prefixlen / 8;
603 :
604 1799 : if (index < 16)
605 : {
606 1695 : pnt = (u_char *) &p->prefix;
607 1695 : offset = p->prefixlen % 8;
608 :
609 1695 : pnt[index] &= maskbit[offset];
610 1695 : index++;
611 :
612 17343 : while (index < 16)
613 13953 : pnt[index++] = 0;
614 : }
615 1799 : }
616 :
617 : void
618 0 : str2in6_addr (const char *str, struct in6_addr *addr)
619 : {
620 : int i;
621 : unsigned int x;
622 :
623 : /* %x must point to unsinged int */
624 0 : for (i = 0; i < 16; i++)
625 : {
626 0 : sscanf (str + (i * 2), "%02x", &x);
627 0 : addr->s6_addr[i] = x & 0xff;
628 : }
629 0 : }
630 : #endif /* HAVE_IPV6 */
631 :
632 : void
633 1327 : apply_mask (struct prefix *p)
634 : {
635 1327 : switch (p->family)
636 : {
637 : case AF_INET:
638 113 : apply_mask_ipv4 ((struct prefix_ipv4 *)p);
639 113 : break;
640 : #ifdef HAVE_IPV6
641 : case AF_INET6:
642 1214 : apply_mask_ipv6 ((struct prefix_ipv6 *)p);
643 1214 : break;
644 : #endif /* HAVE_IPV6 */
645 : default:
646 0 : break;
647 : }
648 1327 : return;
649 : }
650 :
651 : /* Utility function of convert between struct prefix <=> union sockunion.
652 : * FIXME This function isn't used anywhere. */
653 : struct prefix *
654 0 : sockunion2prefix (const union sockunion *dest,
655 : const union sockunion *mask)
656 : {
657 0 : if (dest->sa.sa_family == AF_INET)
658 : {
659 : struct prefix_ipv4 *p;
660 :
661 0 : p = prefix_ipv4_new ();
662 0 : p->family = AF_INET;
663 0 : p->prefix = dest->sin.sin_addr;
664 0 : p->prefixlen = ip_masklen (mask->sin.sin_addr);
665 0 : return (struct prefix *) p;
666 : }
667 : #ifdef HAVE_IPV6
668 0 : if (dest->sa.sa_family == AF_INET6)
669 : {
670 : struct prefix_ipv6 *p;
671 :
672 0 : p = prefix_ipv6_new ();
673 0 : p->family = AF_INET6;
674 0 : p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
675 0 : memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
676 0 : return (struct prefix *) p;
677 : }
678 : #endif /* HAVE_IPV6 */
679 0 : return NULL;
680 : }
681 :
682 : /* Utility function of convert between struct prefix <=> union sockunion. */
683 : struct prefix *
684 0 : sockunion2hostprefix (const union sockunion *su)
685 : {
686 0 : if (su->sa.sa_family == AF_INET)
687 : {
688 : struct prefix_ipv4 *p;
689 :
690 0 : p = prefix_ipv4_new ();
691 0 : p->family = AF_INET;
692 0 : p->prefix = su->sin.sin_addr;
693 0 : p->prefixlen = IPV4_MAX_BITLEN;
694 0 : return (struct prefix *) p;
695 : }
696 : #ifdef HAVE_IPV6
697 0 : if (su->sa.sa_family == AF_INET6)
698 : {
699 : struct prefix_ipv6 *p;
700 :
701 0 : p = prefix_ipv6_new ();
702 0 : p->family = AF_INET6;
703 0 : p->prefixlen = IPV6_MAX_BITLEN;
704 0 : memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
705 0 : return (struct prefix *) p;
706 : }
707 : #endif /* HAVE_IPV6 */
708 0 : return NULL;
709 : }
710 :
711 : void
712 0 : prefix2sockunion (const struct prefix *p, union sockunion *su)
713 : {
714 0 : memset (su, 0, sizeof (*su));
715 :
716 0 : su->sa.sa_family = p->family;
717 0 : if (p->family == AF_INET)
718 0 : su->sin.sin_addr = p->u.prefix4;
719 : #ifdef HAVE_IPV6
720 0 : if (p->family == AF_INET6)
721 0 : memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
722 : #endif /* HAVE_IPV6 */
723 0 : }
724 :
725 : int
726 0 : prefix_blen (const struct prefix *p)
727 : {
728 0 : switch (p->family)
729 : {
730 : case AF_INET:
731 0 : return IPV4_MAX_BYTELEN;
732 : break;
733 : #ifdef HAVE_IPV6
734 : case AF_INET6:
735 0 : return IPV6_MAX_BYTELEN;
736 : break;
737 : #endif /* HAVE_IPV6 */
738 : }
739 0 : return 0;
740 : }
741 :
742 : /* Generic function for conversion string to struct prefix. */
743 : int
744 5 : str2prefix (const char *str, struct prefix *p)
745 : {
746 : int ret;
747 :
748 : /* First we try to convert string to struct prefix_ipv4. */
749 5 : ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
750 5 : if (ret)
751 5 : return ret;
752 :
753 : #ifdef HAVE_IPV6
754 : /* Next we try to convert string to struct prefix_ipv6. */
755 0 : ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
756 0 : if (ret)
757 0 : return ret;
758 : #endif /* HAVE_IPV6 */
759 :
760 0 : return 0;
761 : }
762 :
763 : int
764 43 : prefix2str (const struct prefix *p, char *str, int size)
765 : {
766 : char buf[BUFSIZ];
767 :
768 43 : inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
769 43 : snprintf (str, size, "%s/%d", buf, p->prefixlen);
770 43 : return 0;
771 : }
772 :
773 : struct prefix *
774 283 : prefix_new ()
775 : {
776 : struct prefix *p;
777 :
778 283 : p = XCALLOC (MTYPE_PREFIX, sizeof *p);
779 283 : return p;
780 : }
781 :
782 : /* Free prefix structure. */
783 : void
784 10 : prefix_free (struct prefix *p)
785 : {
786 10 : XFREE (MTYPE_PREFIX, p);
787 10 : }
788 :
789 : /* Utility function. Check the string only contains digit
790 : * character.
791 : * FIXME str.[c|h] would be better place for this function. */
792 : int
793 0 : all_digit (const char *str)
794 : {
795 0 : for (; *str != '\0'; str++)
796 0 : if (!isdigit ((int) *str))
797 0 : return 0;
798 0 : return 1;
799 : }
800 :
801 : /* Utility function to convert ipv4 prefixes to Classful prefixes */
802 0 : void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
803 : {
804 :
805 : u_int32_t destination;
806 :
807 0 : destination = ntohl (p->prefix.s_addr);
808 :
809 0 : if (p->prefixlen == IPV4_MAX_PREFIXLEN);
810 : /* do nothing for host routes */
811 0 : else if (IN_CLASSC (destination))
812 : {
813 0 : p->prefixlen=24;
814 0 : apply_mask_ipv4(p);
815 : }
816 0 : else if (IN_CLASSB(destination))
817 : {
818 0 : p->prefixlen=16;
819 0 : apply_mask_ipv4(p);
820 : }
821 : else
822 : {
823 0 : p->prefixlen=8;
824 0 : apply_mask_ipv4(p);
825 : }
826 0 : }
827 :
828 : in_addr_t
829 0 : ipv4_network_addr (in_addr_t hostaddr, int masklen)
830 : {
831 : struct in_addr mask;
832 :
833 0 : masklen2ip (masklen, &mask);
834 0 : return hostaddr & mask.s_addr;
835 : }
836 :
837 : in_addr_t
838 2 : ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
839 : {
840 : struct in_addr mask;
841 :
842 2 : masklen2ip (masklen, &mask);
843 2 : return (masklen != IPV4_MAX_PREFIXLEN-1) ?
844 : /* normal case */
845 2 : (hostaddr | ~mask.s_addr) :
846 : /* special case for /31 */
847 0 : (hostaddr ^ ~mask.s_addr);
848 : }
849 :
850 : /* Utility function to convert ipv4 netmask to prefixes
851 : ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
852 : ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
853 : int
854 0 : netmask_str2prefix_str (const char *net_str, const char *mask_str,
855 : char *prefix_str)
856 : {
857 : struct in_addr network;
858 : struct in_addr mask;
859 : u_char prefixlen;
860 : u_int32_t destination;
861 : int ret;
862 :
863 0 : ret = inet_aton (net_str, &network);
864 0 : if (! ret)
865 0 : return 0;
866 :
867 0 : if (mask_str)
868 : {
869 0 : ret = inet_aton (mask_str, &mask);
870 0 : if (! ret)
871 0 : return 0;
872 :
873 0 : prefixlen = ip_masklen (mask);
874 : }
875 : else
876 : {
877 0 : destination = ntohl (network.s_addr);
878 :
879 0 : if (network.s_addr == 0)
880 0 : prefixlen = 0;
881 0 : else if (IN_CLASSC (destination))
882 0 : prefixlen = 24;
883 0 : else if (IN_CLASSB (destination))
884 0 : prefixlen = 16;
885 0 : else if (IN_CLASSA (destination))
886 0 : prefixlen = 8;
887 : else
888 0 : return 0;
889 : }
890 :
891 0 : sprintf (prefix_str, "%s/%d", net_str, prefixlen);
892 :
893 0 : return 1;
894 : }
895 :
896 : #ifdef HAVE_IPV6
897 : /* Utility function for making IPv6 address string. */
898 : const char *
899 100 : inet6_ntoa (struct in6_addr addr)
900 : {
901 : static char buf[INET6_ADDRSTRLEN];
902 :
903 100 : inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
904 100 : return buf;
905 : }
906 : #endif /* HAVE_IPV6 */
|