]> git.proxmox.com Git - mirror_frr.git/blob - lib/prefix.c
Merge pull request #410 from dslicenc/rdnbrd-vrr
[mirror_frr.git] / lib / prefix.c
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 DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix")
32
33 /* Maskbit. */
34 static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
35 0xf8, 0xfc, 0xfe, 0xff};
36
37 static const struct in6_addr maskbytes6[] =
38 {
39 /* /0 */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
40 /* /1 */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
41 /* /2 */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
42 /* /3 */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
43 /* /4 */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
44 /* /5 */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
45 /* /6 */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
46 /* /7 */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
47 /* /8 */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
48 /* /9 */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
49 /* /10 */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
50 /* /11 */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
51 /* /12 */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
52 /* /13 */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
53 /* /14 */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
54 /* /15 */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
55 /* /16 */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
56 /* /17 */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
57 /* /18 */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
58 /* /19 */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
59 /* /20 */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
60 /* /21 */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
61 /* /22 */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
62 /* /23 */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
63 /* /24 */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
64 /* /25 */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
65 /* /26 */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
66 /* /27 */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
67 /* /28 */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
68 /* /29 */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
69 /* /30 */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
70 /* /31 */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
71 /* /32 */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
72 /* /33 */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
73 /* /34 */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
74 /* /35 */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
75 /* /36 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
76 /* /37 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
77 /* /38 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
78 /* /39 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
79 /* /40 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
80 /* /41 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
81 /* /42 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
82 /* /43 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
83 /* /44 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
84 /* /45 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
85 /* /46 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
86 /* /47 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
87 /* /48 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
88 /* /49 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
89 /* /50 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
90 /* /51 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
91 /* /52 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
92 /* /53 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
93 /* /54 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
94 /* /55 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
95 /* /56 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
96 /* /57 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
97 /* /58 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
98 /* /59 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
99 /* /60 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
100 /* /61 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
101 /* /62 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
102 /* /63 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
103 /* /64 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
104 /* /65 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
105 /* /66 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
106 /* /67 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
107 /* /68 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
108 /* /69 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
109 /* /70 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
110 /* /71 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
111 /* /72 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
112 /* /73 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
113 /* /74 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
114 /* /75 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
115 /* /76 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
116 /* /77 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
117 /* /78 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
118 /* /79 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
119 /* /80 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
120 /* /81 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
121 /* /82 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
122 /* /83 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
123 /* /84 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
124 /* /85 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
125 /* /86 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
126 /* /87 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
127 /* /88 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
128 /* /89 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } },
129 /* /90 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } },
130 /* /91 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } },
131 /* /92 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } },
132 /* /93 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } },
133 /* /94 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } },
134 /* /95 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } },
135 /* /96 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
136 /* /97 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } },
137 /* /98 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } },
138 /* /99 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } },
139 /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } },
140 /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } },
141 /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } },
142 /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } },
143 /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } },
144 /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } },
145 /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } },
146 /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } },
147 /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } },
148 /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } },
149 /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } },
150 /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } },
151 /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
152 /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } },
153 /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } },
154 /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } },
155 /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } },
156 /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } },
157 /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } },
158 /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } },
159 /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } },
160 /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } },
161 /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } },
162 /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } },
163 /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } },
164 /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } },
165 /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } },
166 /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } },
167 /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
168 };
169
170 /* Number of bits in prefix type. */
171 #ifndef PNBBY
172 #define PNBBY 8
173 #endif /* PNBBY */
174
175 #define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
176
177 unsigned int
178 prefix_bit (const u_char *prefix, const u_char prefixlen)
179 {
180 unsigned int offset = prefixlen / 8;
181 unsigned int shift = 7 - (prefixlen % 8);
182
183 return (prefix[offset] >> shift) & 1;
184 }
185
186 unsigned int
187 prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
188 {
189 return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
190 }
191
192 int
193 str2family(const char *string)
194 {
195 if (!strcmp("ipv4", string))
196 return AF_INET;
197 else if (!strcmp("ipv6", string))
198 return AF_INET6;
199 else if (!strcmp("ethernet", string))
200 return AF_ETHERNET;
201 return -1;
202 }
203
204 /* Address Famiy Identifier to Address Family converter. */
205 int
206 afi2family (afi_t afi)
207 {
208 if (afi == AFI_IP)
209 return AF_INET;
210 else if (afi == AFI_IP6)
211 return AF_INET6;
212 else if (afi == AFI_L2VPN)
213 return AF_ETHERNET;
214 return 0;
215 }
216
217 afi_t
218 family2afi (int family)
219 {
220 if (family == AF_INET)
221 return AFI_IP;
222 else if (family == AF_INET6)
223 return AFI_IP6;
224 else if (family == AF_ETHERNET)
225 return AFI_L2VPN;
226 return 0;
227 }
228
229 const char *
230 afi2str(afi_t afi)
231 {
232 switch (afi) {
233 case AFI_IP:
234 return "IPv4";
235 case AFI_IP6:
236 return "IPv6";
237 case AFI_L2VPN:
238 return "l2vpn";
239 case AFI_MAX:
240 return "bad-value";
241 default:
242 break;
243 }
244 return NULL;
245 }
246
247 const char *
248 safi2str(safi_t safi)
249 {
250 switch (safi) {
251 case SAFI_UNICAST:
252 return "unicast";
253 case SAFI_MULTICAST:
254 return "multicast";
255 case SAFI_ENCAP:
256 return "encap";
257 case SAFI_MPLS_VPN:
258 return "vpn";
259 case SAFI_EVPN:
260 return "evpn";
261 }
262 return NULL;
263 }
264
265 /* If n includes p prefix then return 1 else return 0. */
266 int
267 prefix_match (const struct prefix *n, const struct prefix *p)
268 {
269 int offset;
270 int shift;
271 const u_char *np, *pp;
272
273 /* If n's prefix is longer than p's one return 0. */
274 if (n->prefixlen > p->prefixlen)
275 return 0;
276
277 /* Set both prefix's head pointer. */
278 np = (const u_char *)&n->u.prefix;
279 pp = (const u_char *)&p->u.prefix;
280
281 offset = n->prefixlen / PNBBY;
282 shift = n->prefixlen % PNBBY;
283
284 if (shift)
285 if (maskbit[shift] & (np[offset] ^ pp[offset]))
286 return 0;
287
288 while (offset--)
289 if (np[offset] != pp[offset])
290 return 0;
291 return 1;
292 }
293
294 /* Copy prefix from src to dest. */
295 void
296 prefix_copy (struct prefix *dest, const struct prefix *src)
297 {
298 dest->family = src->family;
299 dest->prefixlen = src->prefixlen;
300
301 if (src->family == AF_INET)
302 dest->u.prefix4 = src->u.prefix4;
303 else if (src->family == AF_INET6)
304 dest->u.prefix6 = src->u.prefix6;
305 else if (src->family == AF_ETHERNET)
306 {
307 memcpy (&dest->u.prefix_evpn, &src->u.prefix_evpn, sizeof (struct evpn_addr));
308 }
309 else if (src->family == AF_UNSPEC)
310 {
311 dest->u.lp.id = src->u.lp.id;
312 dest->u.lp.adv_router = src->u.lp.adv_router;
313 }
314 else
315 {
316 zlog_err("prefix_copy(): Unknown address family %d", src->family);
317 assert (0);
318 }
319 }
320
321 /*
322 * Return 1 if the address/netmask contained in the prefix structure
323 * is the same, and else return 0. For this routine, 'same' requires
324 * that not only the prefix length and the network part be the same,
325 * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
326 * the same. Note that this routine has the same return value sense
327 * as '==' (which is different from prefix_cmp).
328 */
329 int
330 prefix_same (const struct prefix *p1, const struct prefix *p2)
331 {
332 if ((p1 && !p2) || (!p1 && p2))
333 return 0;
334
335 if (!p1 && !p2)
336 return 1;
337
338 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
339 {
340 if (p1->family == AF_INET)
341 if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
342 return 1;
343 if (p1->family == AF_INET6 )
344 if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
345 return 1;
346 if (p1->family == AF_ETHERNET )
347 if (!memcmp (&p1->u.prefix_evpn, &p2->u.prefix_evpn, sizeof (struct evpn_addr)))
348 return 1;
349 }
350 return 0;
351 }
352
353 /*
354 * Return 0 if the network prefixes represented by the struct prefix
355 * arguments are the same prefix, and 1 otherwise. Network prefixes
356 * are considered the same if the prefix lengths are equal and the
357 * network parts are the same. Host bits (which are considered masked
358 * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
359 * 10.0.0.2/8 are considered equivalent by this routine. Note that
360 * this routine has the same return sense as strcmp (which is different
361 * from prefix_same).
362 */
363 int
364 prefix_cmp (const struct prefix *p1, const struct prefix *p2)
365 {
366 int offset;
367 int shift;
368
369 /* Set both prefix's head pointer. */
370 const u_char *pp1 = (const u_char *)&p1->u.prefix;
371 const u_char *pp2 = (const u_char *)&p2->u.prefix;
372
373 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
374 return 1;
375
376 offset = p1->prefixlen / PNBBY;
377 shift = p1->prefixlen % PNBBY;
378
379 if (shift)
380 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
381 return 1;
382
383 while (offset--)
384 if (pp1[offset] != pp2[offset])
385 return 1;
386
387 return 0;
388 }
389
390 /*
391 * Count the number of common bits in 2 prefixes. The prefix length is
392 * ignored for this function; the whole prefix is compared. If the prefix
393 * address families don't match, return -1; otherwise the return value is
394 * in range 0 ... maximum prefix length for the address family.
395 */
396 int
397 prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
398 {
399 int pos, bit;
400 int length = 0;
401 u_char xor;
402
403 /* Set both prefix's head pointer. */
404 const u_char *pp1 = (const u_char *)&p1->u.prefix;
405 const u_char *pp2 = (const u_char *)&p2->u.prefix;
406
407 if (p1->family == AF_INET)
408 length = IPV4_MAX_BYTELEN;
409 if (p1->family == AF_INET6)
410 length = IPV6_MAX_BYTELEN;
411 if (p1->family == AF_ETHERNET)
412 length = 8 * sizeof (struct evpn_addr);
413
414 if (p1->family != p2->family || !length)
415 return -1;
416
417 for (pos = 0; pos < length; pos++)
418 if (pp1[pos] != pp2[pos])
419 break;
420 if (pos == length)
421 return pos * 8;
422
423 xor = pp1[pos] ^ pp2[pos];
424 for (bit = 0; bit < 8; bit++)
425 if (xor & (1 << (7 - bit)))
426 break;
427
428 return pos * 8 + bit;
429 }
430
431 /* Return prefix family type string. */
432 const char *
433 prefix_family_str (const struct prefix *p)
434 {
435 if (p->family == AF_INET)
436 return "inet";
437 if (p->family == AF_INET6)
438 return "inet6";
439 if (p->family == AF_ETHERNET)
440 return "ether";
441 return "unspec";
442 }
443
444 /* Allocate new prefix_ipv4 structure. */
445 struct prefix_ipv4 *
446 prefix_ipv4_new ()
447 {
448 struct prefix_ipv4 *p;
449
450 /* Call prefix_new to allocate a full-size struct prefix to avoid problems
451 where the struct prefix_ipv4 is cast to struct prefix and unallocated
452 bytes were being referenced (e.g. in structure assignments). */
453 p = (struct prefix_ipv4 *)prefix_new();
454 p->family = AF_INET;
455 return p;
456 }
457
458 /* Free prefix_ipv4 structure. */
459 void
460 prefix_ipv4_free (struct prefix_ipv4 *p)
461 {
462 prefix_free((struct prefix *)p);
463 }
464
465 /* When string format is invalid return 0. */
466 int
467 str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
468 {
469 int ret;
470 int plen;
471 char *pnt;
472 char *cp;
473
474 /* Find slash inside string. */
475 pnt = strchr (str, '/');
476
477 /* String doesn't contail slash. */
478 if (pnt == NULL)
479 {
480 /* Convert string to prefix. */
481 ret = inet_aton (str, &p->prefix);
482 if (ret == 0)
483 return 0;
484
485 /* If address doesn't contain slash we assume it host address. */
486 p->family = AF_INET;
487 p->prefixlen = IPV4_MAX_BITLEN;
488
489 return ret;
490 }
491 else
492 {
493 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
494 strncpy (cp, str, pnt - str);
495 *(cp + (pnt - str)) = '\0';
496 ret = inet_aton (cp, &p->prefix);
497 XFREE (MTYPE_TMP, cp);
498
499 /* Get prefix length. */
500 plen = (u_char) atoi (++pnt);
501 if (plen > IPV4_MAX_PREFIXLEN)
502 return 0;
503
504 p->family = AF_INET;
505 p->prefixlen = plen;
506 }
507
508 return ret;
509 }
510
511 /* When string format is invalid return 0. */
512 int
513 str2prefix_eth (const char *str, struct prefix_eth *p)
514 {
515 int ret = 0;
516 int plen = 48;
517 char *pnt;
518 char *cp = NULL;
519 const char *str_addr = str;
520 unsigned int a[6];
521 int i;
522
523 /* Find slash inside string. */
524 pnt = strchr (str, '/');
525
526 if (pnt)
527 {
528 /* Get prefix length. */
529 plen = (u_char) atoi (++pnt);
530 if (plen > 48)
531 {
532 ret = 0;
533 goto done;
534 }
535
536 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
537 strncpy (cp, str, pnt - str);
538 *(cp + (pnt - str)) = '\0';
539
540 str_addr = cp;
541 }
542
543 /* Convert string to prefix. */
544 if (sscanf(str_addr, "%2x:%2x:%2x:%2x:%2x:%2x",
545 a+0, a+1, a+2, a+3, a+4, a+5) != 6)
546 {
547 ret = 0;
548 goto done;
549 }
550 for (i = 0; i < 6; ++i)
551 {
552 p->eth_addr.octet[i] = a[i] & 0xff;
553 }
554 p->prefixlen = plen;
555 p->family = AF_ETHERNET;
556 ret = 1;
557
558 done:
559 if (cp)
560 XFREE (MTYPE_TMP, cp);
561
562 return ret;
563 }
564
565 /* Convert masklen into IP address's netmask (network byte order). */
566 void
567 masklen2ip (const int masklen, struct in_addr *netmask)
568 {
569 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
570
571 /* left shift is only defined for less than the size of the type.
572 * we unconditionally use long long in case the target platform
573 * has defined behaviour for << 32 (or has a 64-bit left shift) */
574
575 if (sizeof(unsigned long long) > 4)
576 netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
577 else
578 netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
579 }
580
581 /* Convert IP address's netmask into integer. We assume netmask is
582 sequential one. Argument netmask should be network byte order. */
583 u_char
584 ip_masklen (struct in_addr netmask)
585 {
586 uint32_t tmp = ~ntohl(netmask.s_addr);
587 if (tmp)
588 /* clz: count leading zeroes. sadly, the behaviour of this builtin
589 * is undefined for a 0 argument, even though most CPUs give 32 */
590 return __builtin_clz(tmp);
591 else
592 return 32;
593 }
594
595 /* Apply mask to IPv4 prefix (network byte order). */
596 void
597 apply_mask_ipv4 (struct prefix_ipv4 *p)
598 {
599 struct in_addr mask;
600 masklen2ip(p->prefixlen, &mask);
601 p->prefix.s_addr &= mask.s_addr;
602 }
603
604 /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
605 int
606 prefix_ipv4_any (const struct prefix_ipv4 *p)
607 {
608 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
609 }
610
611 /* Allocate a new ip version 6 route */
612 struct prefix_ipv6 *
613 prefix_ipv6_new (void)
614 {
615 struct prefix_ipv6 *p;
616
617 /* Allocate a full-size struct prefix to avoid problems with structure
618 size mismatches. */
619 p = (struct prefix_ipv6 *)prefix_new();
620 p->family = AF_INET6;
621 return p;
622 }
623
624 /* Free prefix for IPv6. */
625 void
626 prefix_ipv6_free (struct prefix_ipv6 *p)
627 {
628 prefix_free((struct prefix *)p);
629 }
630
631 /* If given string is valid return pin6 else return NULL */
632 int
633 str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
634 {
635 char *pnt;
636 char *cp;
637 int ret;
638
639 pnt = strchr (str, '/');
640
641 /* If string doesn't contain `/' treat it as host route. */
642 if (pnt == NULL)
643 {
644 ret = inet_pton (AF_INET6, str, &p->prefix);
645 if (ret == 0)
646 return 0;
647 p->prefixlen = IPV6_MAX_BITLEN;
648 }
649 else
650 {
651 int plen;
652
653 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
654 strncpy (cp, str, pnt - str);
655 *(cp + (pnt - str)) = '\0';
656 ret = inet_pton (AF_INET6, cp, &p->prefix);
657 XFREE (MTYPE_TMP, cp);
658 if (ret == 0)
659 return 0;
660 plen = (u_char) atoi (++pnt);
661 if (plen > IPV6_MAX_BITLEN)
662 return 0;
663 p->prefixlen = plen;
664 }
665 p->family = AF_INET6;
666
667 return ret;
668 }
669
670 /* Convert struct in6_addr netmask into integer.
671 * FIXME return u_char as ip_maskleni() does. */
672 int
673 ip6_masklen (struct in6_addr netmask)
674 {
675 int len = 0;
676 unsigned char val;
677 unsigned char *pnt;
678
679 pnt = (unsigned char *) & netmask;
680
681 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
682 {
683 len += 8;
684 pnt++;
685 }
686
687 if (len < IPV6_MAX_BITLEN)
688 {
689 val = *pnt;
690 while (val)
691 {
692 len++;
693 val <<= 1;
694 }
695 }
696 return len;
697 }
698
699 void
700 masklen2ip6 (const int masklen, struct in6_addr *netmask)
701 {
702 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
703 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
704 }
705
706 void
707 apply_mask_ipv6 (struct prefix_ipv6 *p)
708 {
709 u_char *pnt;
710 int index;
711 int offset;
712
713 index = p->prefixlen / 8;
714
715 if (index < 16)
716 {
717 pnt = (u_char *) &p->prefix;
718 offset = p->prefixlen % 8;
719
720 pnt[index] &= maskbit[offset];
721 index++;
722
723 while (index < 16)
724 pnt[index++] = 0;
725 }
726 }
727
728 void
729 apply_mask (struct prefix *p)
730 {
731 switch (p->family)
732 {
733 case AF_INET:
734 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
735 break;
736 case AF_INET6:
737 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
738 break;
739 default:
740 break;
741 }
742 return;
743 }
744
745 /* Utility function of convert between struct prefix <=> union sockunion.
746 * FIXME This function isn't used anywhere. */
747 struct prefix *
748 sockunion2prefix (const union sockunion *dest,
749 const union sockunion *mask)
750 {
751 if (dest->sa.sa_family == AF_INET)
752 {
753 struct prefix_ipv4 *p;
754
755 p = prefix_ipv4_new ();
756 p->family = AF_INET;
757 p->prefix = dest->sin.sin_addr;
758 p->prefixlen = ip_masklen (mask->sin.sin_addr);
759 return (struct prefix *) p;
760 }
761 if (dest->sa.sa_family == AF_INET6)
762 {
763 struct prefix_ipv6 *p;
764
765 p = prefix_ipv6_new ();
766 p->family = AF_INET6;
767 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
768 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
769 return (struct prefix *) p;
770 }
771 return NULL;
772 }
773
774 /* Utility function of convert between struct prefix <=> union sockunion. */
775 struct prefix *
776 sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
777 {
778 if (su->sa.sa_family == AF_INET)
779 {
780 struct prefix_ipv4 *p;
781
782 p = prefix ? (struct prefix_ipv4 *) prefix : prefix_ipv4_new ();
783 p->family = AF_INET;
784 p->prefix = su->sin.sin_addr;
785 p->prefixlen = IPV4_MAX_BITLEN;
786 return (struct prefix *) p;
787 }
788 if (su->sa.sa_family == AF_INET6)
789 {
790 struct prefix_ipv6 *p;
791
792 p = prefix ? (struct prefix_ipv6 *) prefix : prefix_ipv6_new ();
793 p->family = AF_INET6;
794 p->prefixlen = IPV6_MAX_BITLEN;
795 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
796 return (struct prefix *) p;
797 }
798 return NULL;
799 }
800
801 void
802 prefix2sockunion (const struct prefix *p, union sockunion *su)
803 {
804 memset (su, 0, sizeof (*su));
805
806 su->sa.sa_family = p->family;
807 if (p->family == AF_INET)
808 su->sin.sin_addr = p->u.prefix4;
809 if (p->family == AF_INET6)
810 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
811 }
812
813 int
814 prefix_blen (const struct prefix *p)
815 {
816 switch (p->family)
817 {
818 case AF_INET:
819 return IPV4_MAX_BYTELEN;
820 break;
821 case AF_INET6:
822 return IPV6_MAX_BYTELEN;
823 break;
824 case AF_ETHERNET:
825 return ETHER_ADDR_LEN;
826 }
827 return 0;
828 }
829
830 /* Generic function for conversion string to struct prefix. */
831 int
832 str2prefix (const char *str, struct prefix *p)
833 {
834 int ret;
835
836 /* First we try to convert string to struct prefix_ipv4. */
837 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
838 if (ret)
839 return ret;
840
841 /* Next we try to convert string to struct prefix_ipv6. */
842 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
843 if (ret)
844 return ret;
845
846 /* Next we try to convert string to struct prefix_eth. */
847 ret = str2prefix_eth (str, (struct prefix_eth *) p);
848 if (ret)
849 return ret;
850
851 return 0;
852 }
853
854 const char *
855 prefix2str (union prefixconstptr pu, char *str, int size)
856 {
857 const struct prefix *p = pu.p;
858 char buf[PREFIX2STR_BUFFER];
859
860 switch (p->family)
861 {
862 case AF_INET:
863 case AF_INET6:
864 snprintf (str, size, "%s/%d",
865 inet_ntop (p->family, &p->u.prefix, buf, PREFIX2STR_BUFFER),
866 p->prefixlen);
867 break;
868
869 case AF_ETHERNET:
870 if (p->u.prefix_evpn.route_type == 5)
871 {
872 u_char family;
873 family = (p->u.prefix_evpn.flags & (IP_ADDR_V4 | IP_PREFIX_V4)) ?
874 AF_INET : AF_INET6;
875 snprintf (str, size, "[%d]:[%u][%s]/%d",
876 p->u.prefix_evpn.route_type,
877 p->u.prefix_evpn.eth_tag,
878 inet_ntop (family, &p->u.prefix_evpn.ip.addr,
879 buf, PREFIX2STR_BUFFER),
880 p->prefixlen);
881 }
882 else
883 {
884 sprintf (str, "UNK AF_ETHER prefix");
885 snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d",
886 p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1],
887 p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3],
888 p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5],
889 p->prefixlen);
890 }
891 break;
892 default:
893 sprintf (str, "UNK prefix");
894 break;
895 }
896
897 return str;
898 }
899
900 struct prefix *
901 prefix_new ()
902 {
903 struct prefix *p;
904
905 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
906 return p;
907 }
908
909 /* Free prefix structure. */
910 void
911 prefix_free (struct prefix *p)
912 {
913 XFREE (MTYPE_PREFIX, p);
914 }
915
916 /* Utility function. Check the string only contains digit
917 * character.
918 * FIXME str.[c|h] would be better place for this function. */
919 int
920 all_digit (const char *str)
921 {
922 for (; *str != '\0'; str++)
923 if (!isdigit ((int) *str))
924 return 0;
925 return 1;
926 }
927
928 /* Utility function to convert ipv4 prefixes to Classful prefixes */
929 void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
930 {
931
932 u_int32_t destination;
933
934 destination = ntohl (p->prefix.s_addr);
935
936 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
937 /* do nothing for host routes */
938 else if (IN_CLASSC (destination))
939 {
940 p->prefixlen=24;
941 apply_mask_ipv4(p);
942 }
943 else if (IN_CLASSB(destination))
944 {
945 p->prefixlen=16;
946 apply_mask_ipv4(p);
947 }
948 else
949 {
950 p->prefixlen=8;
951 apply_mask_ipv4(p);
952 }
953 }
954
955 in_addr_t
956 ipv4_network_addr (in_addr_t hostaddr, int masklen)
957 {
958 struct in_addr mask;
959
960 masklen2ip (masklen, &mask);
961 return hostaddr & mask.s_addr;
962 }
963
964 in_addr_t
965 ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
966 {
967 struct in_addr mask;
968
969 masklen2ip (masklen, &mask);
970 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
971 /* normal case */
972 (hostaddr | ~mask.s_addr) :
973 /* special case for /31 */
974 (hostaddr ^ ~mask.s_addr);
975 }
976
977 /* Utility function to convert ipv4 netmask to prefixes
978 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
979 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
980 int
981 netmask_str2prefix_str (const char *net_str, const char *mask_str,
982 char *prefix_str)
983 {
984 struct in_addr network;
985 struct in_addr mask;
986 u_char prefixlen;
987 u_int32_t destination;
988 int ret;
989
990 ret = inet_aton (net_str, &network);
991 if (! ret)
992 return 0;
993
994 if (mask_str)
995 {
996 ret = inet_aton (mask_str, &mask);
997 if (! ret)
998 return 0;
999
1000 prefixlen = ip_masklen (mask);
1001 }
1002 else
1003 {
1004 destination = ntohl (network.s_addr);
1005
1006 if (network.s_addr == 0)
1007 prefixlen = 0;
1008 else if (IN_CLASSC (destination))
1009 prefixlen = 24;
1010 else if (IN_CLASSB (destination))
1011 prefixlen = 16;
1012 else if (IN_CLASSA (destination))
1013 prefixlen = 8;
1014 else
1015 return 0;
1016 }
1017
1018 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
1019
1020 return 1;
1021 }
1022
1023 /* Utility function for making IPv6 address string. */
1024 const char *
1025 inet6_ntoa (struct in6_addr addr)
1026 {
1027 static char buf[INET6_ADDRSTRLEN];
1028
1029 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
1030 return buf;
1031 }
1032
1033 /* converts to internal representation of mac address
1034 * returns 1 on success, 0 otherwise
1035 * format accepted: AA:BB:CC:DD:EE:FF
1036 * if mac parameter is null, then check only
1037 */
1038 int prefix_str2mac(const char *str, struct ethaddr *mac)
1039 {
1040 unsigned int a[6];
1041 int i;
1042
1043 if (!str)
1044 return 0;
1045
1046 if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x",
1047 a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6)
1048 {
1049 /* error in incoming str length */
1050 return 0;
1051 }
1052 /* valid mac address */
1053 if (!mac)
1054 return 1;
1055 for (i = 0; i < 6; ++i)
1056 mac->octet[i] = a[i] & 0xff;
1057 return 1;
1058 }
1059
1060 char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size)
1061 {
1062 char *ptr;
1063
1064 if (!mac)
1065 return NULL;
1066 if (!buf)
1067 ptr = (char *)XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN* sizeof(char));
1068 else
1069 {
1070 assert (size >= ETHER_ADDR_STRLEN);
1071 ptr = buf;
1072 }
1073 snprintf(ptr, (ETHER_ADDR_STRLEN),
1074 "%02x:%02x:%02x:%02x:%02x:%02x", (uint8_t) mac->octet[0],
1075 (uint8_t) mac->octet[1], (uint8_t) mac->octet[2], (uint8_t) mac->octet[3],
1076 (uint8_t) mac->octet[4], (uint8_t) mac->octet[5]);
1077 return ptr;
1078 }