blob: 43fc31713016bd9fc99f81efa81c8a62907c8404 [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;
Lou Bergerd83b8d62016-05-17 07:10:41 -0400197 else if (!strcmp("ethernet", string))
198 return AF_ETHERNET;
199 return -1;
Christian Frankeacf98652015-11-12 14:24:22 +0100200}
201
paul718e3742002-12-13 20:15:29 +0000202/* Address Famiy Identifier to Address Family converter. */
203int
Michael Lambert4c9641b2010-07-22 13:20:55 -0400204afi2family (afi_t afi)
paul718e3742002-12-13 20:15:29 +0000205{
206 if (afi == AFI_IP)
207 return AF_INET;
208#ifdef HAVE_IPV6
209 else if (afi == AFI_IP6)
210 return AF_INET6;
211#endif /* HAVE_IPV6 */
Lou Bergerd83b8d62016-05-17 07:10:41 -0400212 else if (afi == AFI_ETHER)
213 return AF_ETHERNET;
paul718e3742002-12-13 20:15:29 +0000214 return 0;
215}
216
Michael Lambert4c9641b2010-07-22 13:20:55 -0400217afi_t
paul718e3742002-12-13 20:15:29 +0000218family2afi (int family)
219{
220 if (family == AF_INET)
221 return AFI_IP;
222#ifdef HAVE_IPV6
223 else if (family == AF_INET6)
224 return AFI_IP6;
225#endif /* HAVE_IPV6 */
Lou Bergerd83b8d62016-05-17 07:10:41 -0400226 else if (family == AF_ETHERNET)
227 return AFI_ETHER;
paul718e3742002-12-13 20:15:29 +0000228 return 0;
229}
230
Lou Berger2daf7f32016-01-12 13:41:50 -0500231const char *
Lou Bergerd83b8d62016-05-17 07:10:41 -0400232afi2str(afi_t afi)
233{
234 switch (afi) {
235 case AFI_IP:
236 return "IPv4";
237 case AFI_IP6:
238 return "IPv6";
239 case AFI_ETHER:
240 return "ethernet";
241 }
242 return NULL;
243}
244
245const char *
Lou Berger2daf7f32016-01-12 13:41:50 -0500246safi2str(safi_t safi)
247{
248 switch (safi) {
249 case SAFI_UNICAST:
250 return "unicast";
251 case SAFI_MULTICAST:
252 return "multicast";
253 case SAFI_ENCAP:
254 return "encap";
255 case SAFI_MPLS_VPN:
256 return "vpn";
257 }
258 return NULL;
259}
260
paul718e3742002-12-13 20:15:29 +0000261/* If n includes p prefix then return 1 else return 0. */
262int
hassob04c6992004-10-04 19:10:31 +0000263prefix_match (const struct prefix *n, const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000264{
265 int offset;
266 int shift;
Paul Jakmad3583442010-01-24 21:41:02 +0000267 const u_char *np, *pp;
paul718e3742002-12-13 20:15:29 +0000268
269 /* If n's prefix is longer than p's one return 0. */
270 if (n->prefixlen > p->prefixlen)
271 return 0;
272
Paul Jakmad3583442010-01-24 21:41:02 +0000273 /* Set both prefix's head pointer. */
274 np = (const u_char *)&n->u.prefix;
275 pp = (const u_char *)&p->u.prefix;
276
paul718e3742002-12-13 20:15:29 +0000277 offset = n->prefixlen / PNBBY;
278 shift = n->prefixlen % PNBBY;
279
280 if (shift)
281 if (maskbit[shift] & (np[offset] ^ pp[offset]))
282 return 0;
283
284 while (offset--)
285 if (np[offset] != pp[offset])
286 return 0;
287 return 1;
288}
289
290/* Copy prefix from src to dest. */
291void
hassob04c6992004-10-04 19:10:31 +0000292prefix_copy (struct prefix *dest, const struct prefix *src)
paul718e3742002-12-13 20:15:29 +0000293{
294 dest->family = src->family;
295 dest->prefixlen = src->prefixlen;
296
297 if (src->family == AF_INET)
298 dest->u.prefix4 = src->u.prefix4;
299#ifdef HAVE_IPV6
300 else if (src->family == AF_INET6)
301 dest->u.prefix6 = src->u.prefix6;
302#endif /* HAVE_IPV6 */
303 else if (src->family == AF_UNSPEC)
304 {
305 dest->u.lp.id = src->u.lp.id;
306 dest->u.lp.adv_router = src->u.lp.adv_router;
307 }
Lou Bergerd83b8d62016-05-17 07:10:41 -0400308 else if (src->family == AF_ETHERNET)
309 {
310 dest->u.prefix_eth = src->u.prefix_eth;
311 }
paul718e3742002-12-13 20:15:29 +0000312 else
313 {
ajsb9e70282004-12-08 17:14:45 +0000314 zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
paul718e3742002-12-13 20:15:29 +0000315 src->family);
316 assert (0);
317 }
318}
319
gdt9d24baa2004-01-13 14:55:40 +0000320/*
321 * Return 1 if the address/netmask contained in the prefix structure
322 * is the same, and else return 0. For this routine, 'same' requires
323 * that not only the prefix length and the network part be the same,
324 * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
325 * the same. Note that this routine has the same return value sense
326 * as '==' (which is different from prefix_cmp).
327 */
paul718e3742002-12-13 20:15:29 +0000328int
hassob04c6992004-10-04 19:10:31 +0000329prefix_same (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000330{
331 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
332 {
333 if (p1->family == AF_INET)
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400334 if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
paul718e3742002-12-13 20:15:29 +0000335 return 1;
336#ifdef HAVE_IPV6
337 if (p1->family == AF_INET6 )
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400338 if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
paul718e3742002-12-13 20:15:29 +0000339 return 1;
340#endif /* HAVE_IPV6 */
Lou Bergerd83b8d62016-05-17 07:10:41 -0400341 if (p1->family == AF_ETHERNET) {
342 if (!memcmp(p1->u.prefix_eth.octet, p2->u.prefix_eth.octet, ETHER_ADDR_LEN))
343 return 1;
344 }
paul718e3742002-12-13 20:15:29 +0000345 }
346 return 0;
347}
348
gdt9d24baa2004-01-13 14:55:40 +0000349/*
350 * Return 0 if the network prefixes represented by the struct prefix
351 * arguments are the same prefix, and 1 otherwise. Network prefixes
352 * are considered the same if the prefix lengths are equal and the
353 * network parts are the same. Host bits (which are considered masked
354 * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
355 * 10.0.0.2/8 are considered equivalent by this routine. Note that
356 * this routine has the same return sense as strcmp (which is different
357 * from prefix_same).
358 */
paul718e3742002-12-13 20:15:29 +0000359int
hassob04c6992004-10-04 19:10:31 +0000360prefix_cmp (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000361{
362 int offset;
363 int shift;
364
365 /* Set both prefix's head pointer. */
paul8cc41982005-05-06 21:25:49 +0000366 const u_char *pp1 = (const u_char *)&p1->u.prefix;
367 const u_char *pp2 = (const u_char *)&p2->u.prefix;
paul718e3742002-12-13 20:15:29 +0000368
369 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
370 return 1;
371
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400372 offset = p1->prefixlen / PNBBY;
373 shift = p1->prefixlen % PNBBY;
paul718e3742002-12-13 20:15:29 +0000374
375 if (shift)
376 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
377 return 1;
378
379 while (offset--)
380 if (pp1[offset] != pp2[offset])
381 return 1;
382
383 return 0;
384}
385
David Lamparter17e52062010-02-02 20:16:35 +0100386/*
387 * Count the number of common bits in 2 prefixes. The prefix length is
388 * ignored for this function; the whole prefix is compared. If the prefix
389 * address families don't match, return -1; otherwise the return value is
390 * in range 0 ... maximum prefix length for the address family.
391 */
392int
393prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
394{
395 int pos, bit;
396 int length = 0;
397 u_char xor;
398
399 /* Set both prefix's head pointer. */
400 const u_char *pp1 = (const u_char *)&p1->u.prefix;
401 const u_char *pp2 = (const u_char *)&p2->u.prefix;
402
403 if (p1->family == AF_INET)
404 length = IPV4_MAX_BYTELEN;
405#ifdef HAVE_IPV6
406 if (p1->family == AF_INET6)
407 length = IPV6_MAX_BYTELEN;
408#endif
409 if (p1->family != p2->family || !length)
410 return -1;
411
412 for (pos = 0; pos < length; pos++)
413 if (pp1[pos] != pp2[pos])
414 break;
415 if (pos == length)
416 return pos * 8;
417
418 xor = pp1[pos] ^ pp2[pos];
419 for (bit = 0; bit < 8; bit++)
420 if (xor & (1 << (7 - bit)))
421 break;
422
423 return pos * 8 + bit;
424}
425
paul718e3742002-12-13 20:15:29 +0000426/* Return prefix family type string. */
hassob04c6992004-10-04 19:10:31 +0000427const char *
428prefix_family_str (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000429{
430 if (p->family == AF_INET)
431 return "inet";
432#ifdef HAVE_IPV6
433 if (p->family == AF_INET6)
434 return "inet6";
435#endif /* HAVE_IPV6 */
Lou Bergerd83b8d62016-05-17 07:10:41 -0400436 if (p->family == AF_ETHERNET)
437 return "ether";
paul718e3742002-12-13 20:15:29 +0000438 return "unspec";
439}
440
441/* Allocate new prefix_ipv4 structure. */
442struct prefix_ipv4 *
443prefix_ipv4_new ()
444{
445 struct prefix_ipv4 *p;
446
ajs7907c6c2005-07-26 19:55:31 +0000447 /* Call prefix_new to allocate a full-size struct prefix to avoid problems
448 where the struct prefix_ipv4 is cast to struct prefix and unallocated
449 bytes were being referenced (e.g. in structure assignments). */
450 p = (struct prefix_ipv4 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000451 p->family = AF_INET;
452 return p;
453}
454
455/* Free prefix_ipv4 structure. */
456void
457prefix_ipv4_free (struct prefix_ipv4 *p)
458{
ajs7907c6c2005-07-26 19:55:31 +0000459 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000460}
461
462/* When string format is invalid return 0. */
463int
hassob04c6992004-10-04 19:10:31 +0000464str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000465{
466 int ret;
467 int plen;
468 char *pnt;
469 char *cp;
470
471 /* Find slash inside string. */
472 pnt = strchr (str, '/');
473
474 /* String doesn't contail slash. */
475 if (pnt == NULL)
476 {
477 /* Convert string to prefix. */
478 ret = inet_aton (str, &p->prefix);
479 if (ret == 0)
480 return 0;
481
482 /* If address doesn't contain slash we assume it host address. */
483 p->family = AF_INET;
484 p->prefixlen = IPV4_MAX_BITLEN;
485
486 return ret;
487 }
488 else
489 {
490 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
491 strncpy (cp, str, pnt - str);
492 *(cp + (pnt - str)) = '\0';
493 ret = inet_aton (cp, &p->prefix);
494 XFREE (MTYPE_TMP, cp);
495
496 /* Get prefix length. */
497 plen = (u_char) atoi (++pnt);
hasso3fb9cd62004-10-19 19:44:43 +0000498 if (plen > IPV4_MAX_PREFIXLEN)
paul718e3742002-12-13 20:15:29 +0000499 return 0;
500
501 p->family = AF_INET;
502 p->prefixlen = plen;
503 }
504
505 return ret;
506}
507
Lou Bergerd83b8d62016-05-17 07:10:41 -0400508/* When string format is invalid return 0. */
509int
510str2prefix_eth (const char *str, struct prefix_eth *p)
511{
512 int ret = 0;
513 int plen = 48;
514 char *pnt;
515 char *cp = NULL;
516 const char *str_addr = str;
517 unsigned int a[6];
518 int i;
519
520 /* Find slash inside string. */
521 pnt = strchr (str, '/');
522
523 if (pnt)
524 {
525 /* Get prefix length. */
526 plen = (u_char) atoi (++pnt);
527 if (plen > 48)
528 {
529 ret = 0;
530 goto done;
531 }
532
533 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
534 strncpy (cp, str, pnt - str);
535 *(cp + (pnt - str)) = '\0';
536
537 str_addr = cp;
538 }
539
540 /* Convert string to prefix. */
541 if (sscanf(str_addr, "%2x:%2x:%2x:%2x:%2x:%2x",
542 a+0, a+1, a+2, a+3, a+4, a+5) != 6)
543 {
544 ret = 0;
545 goto done;
546 }
547 for (i = 0; i < 6; ++i)
548 {
549 p->eth_addr.octet[i] = a[i] & 0xff;
550 }
551 p->prefixlen = plen;
552 p->family = AF_ETHERNET;
553 ret = 1;
554
555done:
556 if (cp)
557 XFREE (MTYPE_TMP, cp);
558
559 return ret;
560}
561
Denis Ovsienko051954f2011-10-11 15:17:45 +0400562/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000563void
Denis Ovsienko96633862011-10-08 18:15:21 +0400564masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000565{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400566 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
David Lampartere96b3122012-04-04 00:14:36 +0200567
568 /* left shift is only defined for less than the size of the type.
569 * we unconditionally use long long in case the target platform
570 * has defined behaviour for << 32 (or has a 64-bit left shift) */
571
572 if (sizeof(unsigned long long) > 4)
573 netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
574 else
575 netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
paul718e3742002-12-13 20:15:29 +0000576}
577
578/* Convert IP address's netmask into integer. We assume netmask is
579 sequential one. Argument netmask should be network byte order. */
580u_char
581ip_masklen (struct in_addr netmask)
582{
David Lampartere96b3122012-04-04 00:14:36 +0200583 uint32_t tmp = ~ntohl(netmask.s_addr);
584 if (tmp)
585 /* clz: count leading zeroes. sadly, the behaviour of this builtin
586 * is undefined for a 0 argument, even though most CPUs give 32 */
587 return __builtin_clz(tmp);
588 else
589 return 32;
paul718e3742002-12-13 20:15:29 +0000590}
591
Denis Ovsienkocaff7902011-10-18 18:33:53 +0400592/* Apply mask to IPv4 prefix (network byte order). */
paul718e3742002-12-13 20:15:29 +0000593void
594apply_mask_ipv4 (struct prefix_ipv4 *p)
595{
David Lampartere96b3122012-04-04 00:14:36 +0200596 struct in_addr mask;
597 masklen2ip(p->prefixlen, &mask);
598 p->prefix.s_addr &= mask.s_addr;
paul718e3742002-12-13 20:15:29 +0000599}
600
601/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
602int
hassob04c6992004-10-04 19:10:31 +0000603prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000604{
605 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
606}
David Lamparter6b0655a2014-06-04 06:53:35 +0200607
paul718e3742002-12-13 20:15:29 +0000608#ifdef HAVE_IPV6
609
610/* Allocate a new ip version 6 route */
611struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000612prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000613{
614 struct prefix_ipv6 *p;
615
ajs7907c6c2005-07-26 19:55:31 +0000616 /* Allocate a full-size struct prefix to avoid problems with structure
617 size mismatches. */
618 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000619 p->family = AF_INET6;
620 return p;
621}
622
623/* Free prefix for IPv6. */
624void
625prefix_ipv6_free (struct prefix_ipv6 *p)
626{
ajs7907c6c2005-07-26 19:55:31 +0000627 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000628}
629
630/* If given string is valid return pin6 else return NULL */
631int
hassob04c6992004-10-04 19:10:31 +0000632str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000633{
634 char *pnt;
635 char *cp;
636 int ret;
637
638 pnt = strchr (str, '/');
639
640 /* If string doesn't contain `/' treat it as host route. */
641 if (pnt == NULL)
642 {
643 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100644 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000645 return 0;
646 p->prefixlen = IPV6_MAX_BITLEN;
647 }
648 else
649 {
650 int plen;
651
David Lamparter23757db2016-02-24 06:26:02 +0100652 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
paul718e3742002-12-13 20:15:29 +0000653 strncpy (cp, str, pnt - str);
654 *(cp + (pnt - str)) = '\0';
655 ret = inet_pton (AF_INET6, cp, &p->prefix);
656 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100657 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000658 return 0;
659 plen = (u_char) atoi (++pnt);
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400660 if (plen > IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000661 return 0;
662 p->prefixlen = plen;
663 }
664 p->family = AF_INET6;
665
666 return ret;
667}
668
hassob04c6992004-10-04 19:10:31 +0000669/* Convert struct in6_addr netmask into integer.
670 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000671int
672ip6_masklen (struct in6_addr netmask)
673{
674 int len = 0;
675 unsigned char val;
676 unsigned char *pnt;
677
678 pnt = (unsigned char *) & netmask;
679
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400680 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000681 {
682 len += 8;
683 pnt++;
684 }
685
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400686 if (len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000687 {
688 val = *pnt;
689 while (val)
690 {
691 len++;
692 val <<= 1;
693 }
694 }
695 return len;
696}
697
698void
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400699masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000700{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400701 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400702 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000703}
704
705void
706apply_mask_ipv6 (struct prefix_ipv6 *p)
707{
Denis Ovsienko8c7f49d2012-01-01 16:33:12 +0400708 u_char *pnt;
709 int index;
710 int offset;
711
712 index = p->prefixlen / 8;
713
714 if (index < 16)
715 {
716 pnt = (u_char *) &p->prefix;
717 offset = p->prefixlen % 8;
718
719 pnt[index] &= maskbit[offset];
720 index++;
721
722 while (index < 16)
723 pnt[index++] = 0;
724 }
paul718e3742002-12-13 20:15:29 +0000725}
726
727void
hassob04c6992004-10-04 19:10:31 +0000728str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000729{
730 int i;
731 unsigned int x;
732
733 /* %x must point to unsinged int */
734 for (i = 0; i < 16; i++)
735 {
736 sscanf (str + (i * 2), "%02x", &x);
737 addr->s6_addr[i] = x & 0xff;
738 }
739}
740#endif /* HAVE_IPV6 */
741
742void
743apply_mask (struct prefix *p)
744{
745 switch (p->family)
746 {
747 case AF_INET:
748 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
749 break;
750#ifdef HAVE_IPV6
751 case AF_INET6:
752 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
753 break;
754#endif /* HAVE_IPV6 */
755 default:
756 break;
757 }
758 return;
759}
760
hassob04c6992004-10-04 19:10:31 +0000761/* Utility function of convert between struct prefix <=> union sockunion.
762 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000763struct prefix *
hassob04c6992004-10-04 19:10:31 +0000764sockunion2prefix (const union sockunion *dest,
765 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000766{
767 if (dest->sa.sa_family == AF_INET)
768 {
769 struct prefix_ipv4 *p;
770
771 p = prefix_ipv4_new ();
772 p->family = AF_INET;
773 p->prefix = dest->sin.sin_addr;
774 p->prefixlen = ip_masklen (mask->sin.sin_addr);
775 return (struct prefix *) p;
776 }
777#ifdef HAVE_IPV6
778 if (dest->sa.sa_family == AF_INET6)
779 {
780 struct prefix_ipv6 *p;
781
782 p = prefix_ipv6_new ();
783 p->family = AF_INET6;
784 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
785 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
786 return (struct prefix *) p;
787 }
788#endif /* HAVE_IPV6 */
789 return NULL;
790}
791
hassob04c6992004-10-04 19:10:31 +0000792/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000793struct prefix *
Timo Teräsc1c69e42015-05-22 13:40:57 +0300794sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
paul718e3742002-12-13 20:15:29 +0000795{
796 if (su->sa.sa_family == AF_INET)
797 {
798 struct prefix_ipv4 *p;
799
Timo Teräsc1c69e42015-05-22 13:40:57 +0300800 p = prefix ? (struct prefix_ipv4 *) prefix : prefix_ipv4_new ();
paul718e3742002-12-13 20:15:29 +0000801 p->family = AF_INET;
802 p->prefix = su->sin.sin_addr;
803 p->prefixlen = IPV4_MAX_BITLEN;
804 return (struct prefix *) p;
805 }
806#ifdef HAVE_IPV6
807 if (su->sa.sa_family == AF_INET6)
808 {
809 struct prefix_ipv6 *p;
810
Timo Teräsc1c69e42015-05-22 13:40:57 +0300811 p = prefix ? (struct prefix_ipv6 *) prefix : prefix_ipv6_new ();
paul718e3742002-12-13 20:15:29 +0000812 p->family = AF_INET6;
813 p->prefixlen = IPV6_MAX_BITLEN;
814 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
815 return (struct prefix *) p;
816 }
817#endif /* HAVE_IPV6 */
818 return NULL;
819}
820
David Lamparter17e52062010-02-02 20:16:35 +0100821void
822prefix2sockunion (const struct prefix *p, union sockunion *su)
823{
824 memset (su, 0, sizeof (*su));
825
826 su->sa.sa_family = p->family;
827 if (p->family == AF_INET)
828 su->sin.sin_addr = p->u.prefix4;
829#ifdef HAVE_IPV6
830 if (p->family == AF_INET6)
831 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
832#endif /* HAVE_IPV6 */
833}
834
paul718e3742002-12-13 20:15:29 +0000835int
hassob04c6992004-10-04 19:10:31 +0000836prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000837{
838 switch (p->family)
839 {
840 case AF_INET:
841 return IPV4_MAX_BYTELEN;
842 break;
843#ifdef HAVE_IPV6
844 case AF_INET6:
845 return IPV6_MAX_BYTELEN;
846 break;
847#endif /* HAVE_IPV6 */
Lou Bergerd83b8d62016-05-17 07:10:41 -0400848 case AF_ETHERNET:
849 return ETHER_ADDR_LEN;
paul718e3742002-12-13 20:15:29 +0000850 }
851 return 0;
852}
853
854/* Generic function for conversion string to struct prefix. */
855int
hassob04c6992004-10-04 19:10:31 +0000856str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000857{
858 int ret;
859
860 /* First we try to convert string to struct prefix_ipv4. */
861 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
862 if (ret)
863 return ret;
864
865#ifdef HAVE_IPV6
866 /* Next we try to convert string to struct prefix_ipv6. */
867 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
868 if (ret)
869 return ret;
870#endif /* HAVE_IPV6 */
871
Lou Bergerd83b8d62016-05-17 07:10:41 -0400872 /* Next we try to convert string to struct prefix_eth. */
873 ret = str2prefix_eth (str, (struct prefix_eth *) p);
874 if (ret)
875 return ret;
876
paul718e3742002-12-13 20:15:29 +0000877 return 0;
878}
879
Timo Teräs41eb9a42015-05-23 11:08:39 +0300880const char *
881prefix2str (union prefix46constptr pu, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000882{
Timo Teräs41eb9a42015-05-23 11:08:39 +0300883 const struct prefix *p = pu.p;
paul718e3742002-12-13 20:15:29 +0000884 char buf[BUFSIZ];
885
Lou Bergerd83b8d62016-05-17 07:10:41 -0400886 if (p->family == AF_ETHERNET) {
887 int i;
888 char *s = str;
889
890 assert(size > (3*ETHER_ADDR_LEN) + 1 /* slash */ + 3 /* plen */ );
891 for (i = 0; i < ETHER_ADDR_LEN; ++i) {
892 sprintf(s, "%02x", p->u.prefix_eth.octet[i]);
893 if (i < (ETHER_ADDR_LEN - 1)) {
894 *(s+2) = ':';
895 s += 3;
896 } else {
897 s += 2;
898 }
899 }
900 sprintf(s, "/%d", p->prefixlen);
901 return 0;
902 }
903
paul718e3742002-12-13 20:15:29 +0000904 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
905 snprintf (str, size, "%s/%d", buf, p->prefixlen);
Timo Teräs41eb9a42015-05-23 11:08:39 +0300906 return str;
paul718e3742002-12-13 20:15:29 +0000907}
908
909struct prefix *
910prefix_new ()
911{
912 struct prefix *p;
913
914 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
915 return p;
916}
917
918/* Free prefix structure. */
919void
920prefix_free (struct prefix *p)
921{
922 XFREE (MTYPE_PREFIX, p);
923}
924
925/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000926 * character.
927 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000928int
hassob04c6992004-10-04 19:10:31 +0000929all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000930{
931 for (; *str != '\0'; str++)
932 if (!isdigit ((int) *str))
933 return 0;
934 return 1;
935}
936
937/* Utility function to convert ipv4 prefixes to Classful prefixes */
938void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
939{
940
941 u_int32_t destination;
942
943 destination = ntohl (p->prefix.s_addr);
944
hasso3fb9cd62004-10-19 19:44:43 +0000945 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000946 /* do nothing for host routes */
947 else if (IN_CLASSC (destination))
948 {
949 p->prefixlen=24;
950 apply_mask_ipv4(p);
951 }
952 else if (IN_CLASSB(destination))
953 {
954 p->prefixlen=16;
955 apply_mask_ipv4(p);
956 }
957 else
958 {
959 p->prefixlen=8;
960 apply_mask_ipv4(p);
961 }
962}
963
hasso3fb9cd62004-10-19 19:44:43 +0000964in_addr_t
965ipv4_network_addr (in_addr_t hostaddr, int masklen)
966{
967 struct in_addr mask;
968
969 masklen2ip (masklen, &mask);
970 return hostaddr & mask.s_addr;
971}
972
973in_addr_t
974ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
975{
976 struct in_addr mask;
977
978 masklen2ip (masklen, &mask);
979 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
980 /* normal case */
981 (hostaddr | ~mask.s_addr) :
982 /* special case for /31 */
983 (hostaddr ^ ~mask.s_addr);
984}
985
paul718e3742002-12-13 20:15:29 +0000986/* Utility function to convert ipv4 netmask to prefixes
987 ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
988 ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
989int
hassob04c6992004-10-04 19:10:31 +0000990netmask_str2prefix_str (const char *net_str, const char *mask_str,
991 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000992{
993 struct in_addr network;
994 struct in_addr mask;
995 u_char prefixlen;
996 u_int32_t destination;
997 int ret;
998
999 ret = inet_aton (net_str, &network);
1000 if (! ret)
1001 return 0;
1002
1003 if (mask_str)
1004 {
1005 ret = inet_aton (mask_str, &mask);
1006 if (! ret)
1007 return 0;
1008
1009 prefixlen = ip_masklen (mask);
1010 }
1011 else
1012 {
1013 destination = ntohl (network.s_addr);
1014
1015 if (network.s_addr == 0)
1016 prefixlen = 0;
1017 else if (IN_CLASSC (destination))
1018 prefixlen = 24;
1019 else if (IN_CLASSB (destination))
1020 prefixlen = 16;
1021 else if (IN_CLASSA (destination))
1022 prefixlen = 8;
1023 else
1024 return 0;
1025 }
1026
1027 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
1028
1029 return 1;
1030}
1031
hasso59209902005-04-05 14:36:49 +00001032#ifdef HAVE_IPV6
1033/* Utility function for making IPv6 address string. */
1034const char *
hasso3a2ce6a2005-04-08 01:30:51 +00001035inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +00001036{
1037 static char buf[INET6_ADDRSTRLEN];
1038
hasso3a2ce6a2005-04-08 01:30:51 +00001039 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +00001040 return buf;
1041}
1042#endif /* HAVE_IPV6 */