blob: dbfdc83012d564f830b797dc5ad115c42242d0f7 [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
paul718e3742002-12-13 20:15:29 +0000190/* Address Famiy Identifier to Address Family converter. */
191int
Michael Lambert4c9641b2010-07-22 13:20:55 -0400192afi2family (afi_t afi)
paul718e3742002-12-13 20:15:29 +0000193{
194 if (afi == AFI_IP)
195 return AF_INET;
196#ifdef HAVE_IPV6
197 else if (afi == AFI_IP6)
198 return AF_INET6;
199#endif /* HAVE_IPV6 */
200 return 0;
201}
202
Michael Lambert4c9641b2010-07-22 13:20:55 -0400203afi_t
paul718e3742002-12-13 20:15:29 +0000204family2afi (int family)
205{
206 if (family == AF_INET)
207 return AFI_IP;
208#ifdef HAVE_IPV6
209 else if (family == AF_INET6)
210 return AFI_IP6;
211#endif /* HAVE_IPV6 */
212 return 0;
213}
214
215/* If n includes p prefix then return 1 else return 0. */
216int
hassob04c6992004-10-04 19:10:31 +0000217prefix_match (const struct prefix *n, const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000218{
219 int offset;
220 int shift;
Paul Jakmad3583442010-01-24 21:41:02 +0000221 const u_char *np, *pp;
paul718e3742002-12-13 20:15:29 +0000222
223 /* If n's prefix is longer than p's one return 0. */
224 if (n->prefixlen > p->prefixlen)
225 return 0;
226
Paul Jakmad3583442010-01-24 21:41:02 +0000227 /* Set both prefix's head pointer. */
228 np = (const u_char *)&n->u.prefix;
229 pp = (const u_char *)&p->u.prefix;
230
paul718e3742002-12-13 20:15:29 +0000231 offset = n->prefixlen / PNBBY;
232 shift = n->prefixlen % PNBBY;
233
234 if (shift)
235 if (maskbit[shift] & (np[offset] ^ pp[offset]))
236 return 0;
237
238 while (offset--)
239 if (np[offset] != pp[offset])
240 return 0;
241 return 1;
242}
243
244/* Copy prefix from src to dest. */
245void
hassob04c6992004-10-04 19:10:31 +0000246prefix_copy (struct prefix *dest, const struct prefix *src)
paul718e3742002-12-13 20:15:29 +0000247{
248 dest->family = src->family;
249 dest->prefixlen = src->prefixlen;
250
251 if (src->family == AF_INET)
252 dest->u.prefix4 = src->u.prefix4;
253#ifdef HAVE_IPV6
254 else if (src->family == AF_INET6)
255 dest->u.prefix6 = src->u.prefix6;
256#endif /* HAVE_IPV6 */
257 else if (src->family == AF_UNSPEC)
258 {
259 dest->u.lp.id = src->u.lp.id;
260 dest->u.lp.adv_router = src->u.lp.adv_router;
261 }
262 else
263 {
ajsb9e70282004-12-08 17:14:45 +0000264 zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
paul718e3742002-12-13 20:15:29 +0000265 src->family);
266 assert (0);
267 }
268}
269
gdt9d24baa2004-01-13 14:55:40 +0000270/*
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 */
paul718e3742002-12-13 20:15:29 +0000278int
hassob04c6992004-10-04 19:10:31 +0000279prefix_same (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000280{
281 if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
282 {
283 if (p1->family == AF_INET)
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400284 if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
paul718e3742002-12-13 20:15:29 +0000285 return 1;
286#ifdef HAVE_IPV6
287 if (p1->family == AF_INET6 )
Denis Ovsienkofe40bfa2011-12-18 15:40:17 +0400288 if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
paul718e3742002-12-13 20:15:29 +0000289 return 1;
290#endif /* HAVE_IPV6 */
291 }
292 return 0;
293}
294
gdt9d24baa2004-01-13 14:55:40 +0000295/*
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 */
paul718e3742002-12-13 20:15:29 +0000305int
hassob04c6992004-10-04 19:10:31 +0000306prefix_cmp (const struct prefix *p1, const struct prefix *p2)
paul718e3742002-12-13 20:15:29 +0000307{
308 int offset;
309 int shift;
310
311 /* Set both prefix's head pointer. */
paul8cc41982005-05-06 21:25:49 +0000312 const u_char *pp1 = (const u_char *)&p1->u.prefix;
313 const u_char *pp2 = (const u_char *)&p2->u.prefix;
paul718e3742002-12-13 20:15:29 +0000314
315 if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
316 return 1;
317
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400318 offset = p1->prefixlen / PNBBY;
319 shift = p1->prefixlen % PNBBY;
paul718e3742002-12-13 20:15:29 +0000320
321 if (shift)
322 if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
323 return 1;
324
325 while (offset--)
326 if (pp1[offset] != pp2[offset])
327 return 1;
328
329 return 0;
330}
331
David Lamparter17e52062010-02-02 20:16:35 +0100332/*
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 */
338int
339prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
340{
341 int pos, bit;
342 int length = 0;
343 u_char xor;
344
345 /* Set both prefix's head pointer. */
346 const u_char *pp1 = (const u_char *)&p1->u.prefix;
347 const u_char *pp2 = (const u_char *)&p2->u.prefix;
348
349 if (p1->family == AF_INET)
350 length = IPV4_MAX_BYTELEN;
351#ifdef HAVE_IPV6
352 if (p1->family == AF_INET6)
353 length = IPV6_MAX_BYTELEN;
354#endif
355 if (p1->family != p2->family || !length)
356 return -1;
357
358 for (pos = 0; pos < length; pos++)
359 if (pp1[pos] != pp2[pos])
360 break;
361 if (pos == length)
362 return pos * 8;
363
364 xor = pp1[pos] ^ pp2[pos];
365 for (bit = 0; bit < 8; bit++)
366 if (xor & (1 << (7 - bit)))
367 break;
368
369 return pos * 8 + bit;
370}
371
paul718e3742002-12-13 20:15:29 +0000372/* Return prefix family type string. */
hassob04c6992004-10-04 19:10:31 +0000373const char *
374prefix_family_str (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000375{
376 if (p->family == AF_INET)
377 return "inet";
378#ifdef HAVE_IPV6
379 if (p->family == AF_INET6)
380 return "inet6";
381#endif /* HAVE_IPV6 */
382 return "unspec";
383}
384
385/* Allocate new prefix_ipv4 structure. */
386struct prefix_ipv4 *
387prefix_ipv4_new ()
388{
389 struct prefix_ipv4 *p;
390
ajs7907c6c2005-07-26 19:55:31 +0000391 /* 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 p = (struct prefix_ipv4 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000395 p->family = AF_INET;
396 return p;
397}
398
399/* Free prefix_ipv4 structure. */
400void
401prefix_ipv4_free (struct prefix_ipv4 *p)
402{
ajs7907c6c2005-07-26 19:55:31 +0000403 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000404}
405
406/* When string format is invalid return 0. */
407int
hassob04c6992004-10-04 19:10:31 +0000408str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000409{
410 int ret;
411 int plen;
412 char *pnt;
413 char *cp;
414
415 /* Find slash inside string. */
416 pnt = strchr (str, '/');
417
418 /* String doesn't contail slash. */
419 if (pnt == NULL)
420 {
421 /* Convert string to prefix. */
422 ret = inet_aton (str, &p->prefix);
423 if (ret == 0)
424 return 0;
425
426 /* If address doesn't contain slash we assume it host address. */
427 p->family = AF_INET;
428 p->prefixlen = IPV4_MAX_BITLEN;
429
430 return ret;
431 }
432 else
433 {
434 cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
435 strncpy (cp, str, pnt - str);
436 *(cp + (pnt - str)) = '\0';
437 ret = inet_aton (cp, &p->prefix);
438 XFREE (MTYPE_TMP, cp);
439
440 /* Get prefix length. */
441 plen = (u_char) atoi (++pnt);
hasso3fb9cd62004-10-19 19:44:43 +0000442 if (plen > IPV4_MAX_PREFIXLEN)
paul718e3742002-12-13 20:15:29 +0000443 return 0;
444
445 p->family = AF_INET;
446 p->prefixlen = plen;
447 }
448
449 return ret;
450}
451
Denis Ovsienko051954f2011-10-11 15:17:45 +0400452/* Convert masklen into IP address's netmask (network byte order). */
paul718e3742002-12-13 20:15:29 +0000453void
Denis Ovsienko96633862011-10-08 18:15:21 +0400454masklen2ip (const int masklen, struct in_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000455{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400456 assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
David Lampartere96b3122012-04-04 00:14:36 +0200457
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 netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
464 else
465 netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
paul718e3742002-12-13 20:15:29 +0000466}
467
468/* Convert IP address's netmask into integer. We assume netmask is
469 sequential one. Argument netmask should be network byte order. */
470u_char
471ip_masklen (struct in_addr netmask)
472{
David Lampartere96b3122012-04-04 00:14:36 +0200473 uint32_t tmp = ~ntohl(netmask.s_addr);
474 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 return __builtin_clz(tmp);
478 else
479 return 32;
paul718e3742002-12-13 20:15:29 +0000480}
481
Denis Ovsienkocaff7902011-10-18 18:33:53 +0400482/* Apply mask to IPv4 prefix (network byte order). */
paul718e3742002-12-13 20:15:29 +0000483void
484apply_mask_ipv4 (struct prefix_ipv4 *p)
485{
David Lampartere96b3122012-04-04 00:14:36 +0200486 struct in_addr mask;
487 masklen2ip(p->prefixlen, &mask);
488 p->prefix.s_addr &= mask.s_addr;
paul718e3742002-12-13 20:15:29 +0000489}
490
491/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
492int
hassob04c6992004-10-04 19:10:31 +0000493prefix_ipv4_any (const struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +0000494{
495 return (p->prefix.s_addr == 0 && p->prefixlen == 0);
496}
David Lamparter6b0655a2014-06-04 06:53:35 +0200497
paul718e3742002-12-13 20:15:29 +0000498#ifdef HAVE_IPV6
499
500/* Allocate a new ip version 6 route */
501struct prefix_ipv6 *
paul8cc41982005-05-06 21:25:49 +0000502prefix_ipv6_new (void)
paul718e3742002-12-13 20:15:29 +0000503{
504 struct prefix_ipv6 *p;
505
ajs7907c6c2005-07-26 19:55:31 +0000506 /* Allocate a full-size struct prefix to avoid problems with structure
507 size mismatches. */
508 p = (struct prefix_ipv6 *)prefix_new();
paul718e3742002-12-13 20:15:29 +0000509 p->family = AF_INET6;
510 return p;
511}
512
513/* Free prefix for IPv6. */
514void
515prefix_ipv6_free (struct prefix_ipv6 *p)
516{
ajs7907c6c2005-07-26 19:55:31 +0000517 prefix_free((struct prefix *)p);
paul718e3742002-12-13 20:15:29 +0000518}
519
520/* If given string is valid return pin6 else return NULL */
521int
hassob04c6992004-10-04 19:10:31 +0000522str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
paul718e3742002-12-13 20:15:29 +0000523{
524 char *pnt;
525 char *cp;
526 int ret;
527
528 pnt = strchr (str, '/');
529
530 /* If string doesn't contain `/' treat it as host route. */
531 if (pnt == NULL)
532 {
533 ret = inet_pton (AF_INET6, str, &p->prefix);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100534 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000535 return 0;
536 p->prefixlen = IPV6_MAX_BITLEN;
537 }
538 else
539 {
540 int plen;
541
542 cp = XMALLOC (0, (pnt - str) + 1);
543 strncpy (cp, str, pnt - str);
544 *(cp + (pnt - str)) = '\0';
545 ret = inet_pton (AF_INET6, cp, &p->prefix);
546 free (cp);
Paul Jakmac4cf0952009-08-08 20:41:39 +0100547 if (ret == 0)
paul718e3742002-12-13 20:15:29 +0000548 return 0;
549 plen = (u_char) atoi (++pnt);
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400550 if (plen > IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000551 return 0;
552 p->prefixlen = plen;
553 }
554 p->family = AF_INET6;
555
556 return ret;
557}
558
hassob04c6992004-10-04 19:10:31 +0000559/* Convert struct in6_addr netmask into integer.
560 * FIXME return u_char as ip_maskleni() does. */
paul718e3742002-12-13 20:15:29 +0000561int
562ip6_masklen (struct in6_addr netmask)
563{
564 int len = 0;
565 unsigned char val;
566 unsigned char *pnt;
567
568 pnt = (unsigned char *) & netmask;
569
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400570 while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000571 {
572 len += 8;
573 pnt++;
574 }
575
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400576 if (len < IPV6_MAX_BITLEN)
paul718e3742002-12-13 20:15:29 +0000577 {
578 val = *pnt;
579 while (val)
580 {
581 len++;
582 val <<= 1;
583 }
584 }
585 return len;
586}
587
588void
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400589masklen2ip6 (const int masklen, struct in6_addr *netmask)
paul718e3742002-12-13 20:15:29 +0000590{
Denis Ovsienko9ed79b52011-10-24 18:45:05 +0400591 assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
Denis Ovsienko21f569e2011-10-17 21:11:10 +0400592 memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
paul718e3742002-12-13 20:15:29 +0000593}
594
595void
596apply_mask_ipv6 (struct prefix_ipv6 *p)
597{
Denis Ovsienko8c7f49d2012-01-01 16:33:12 +0400598 u_char *pnt;
599 int index;
600 int offset;
601
602 index = p->prefixlen / 8;
603
604 if (index < 16)
605 {
606 pnt = (u_char *) &p->prefix;
607 offset = p->prefixlen % 8;
608
609 pnt[index] &= maskbit[offset];
610 index++;
611
612 while (index < 16)
613 pnt[index++] = 0;
614 }
paul718e3742002-12-13 20:15:29 +0000615}
616
617void
hassob04c6992004-10-04 19:10:31 +0000618str2in6_addr (const char *str, struct in6_addr *addr)
paul718e3742002-12-13 20:15:29 +0000619{
620 int i;
621 unsigned int x;
622
623 /* %x must point to unsinged int */
624 for (i = 0; i < 16; i++)
625 {
626 sscanf (str + (i * 2), "%02x", &x);
627 addr->s6_addr[i] = x & 0xff;
628 }
629}
630#endif /* HAVE_IPV6 */
631
632void
633apply_mask (struct prefix *p)
634{
635 switch (p->family)
636 {
637 case AF_INET:
638 apply_mask_ipv4 ((struct prefix_ipv4 *)p);
639 break;
640#ifdef HAVE_IPV6
641 case AF_INET6:
642 apply_mask_ipv6 ((struct prefix_ipv6 *)p);
643 break;
644#endif /* HAVE_IPV6 */
645 default:
646 break;
647 }
648 return;
649}
650
hassob04c6992004-10-04 19:10:31 +0000651/* Utility function of convert between struct prefix <=> union sockunion.
652 * FIXME This function isn't used anywhere. */
paul718e3742002-12-13 20:15:29 +0000653struct prefix *
hassob04c6992004-10-04 19:10:31 +0000654sockunion2prefix (const union sockunion *dest,
655 const union sockunion *mask)
paul718e3742002-12-13 20:15:29 +0000656{
657 if (dest->sa.sa_family == AF_INET)
658 {
659 struct prefix_ipv4 *p;
660
661 p = prefix_ipv4_new ();
662 p->family = AF_INET;
663 p->prefix = dest->sin.sin_addr;
664 p->prefixlen = ip_masklen (mask->sin.sin_addr);
665 return (struct prefix *) p;
666 }
667#ifdef HAVE_IPV6
668 if (dest->sa.sa_family == AF_INET6)
669 {
670 struct prefix_ipv6 *p;
671
672 p = prefix_ipv6_new ();
673 p->family = AF_INET6;
674 p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
675 memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
676 return (struct prefix *) p;
677 }
678#endif /* HAVE_IPV6 */
679 return NULL;
680}
681
hassob04c6992004-10-04 19:10:31 +0000682/* Utility function of convert between struct prefix <=> union sockunion. */
paul718e3742002-12-13 20:15:29 +0000683struct prefix *
hassob04c6992004-10-04 19:10:31 +0000684sockunion2hostprefix (const union sockunion *su)
paul718e3742002-12-13 20:15:29 +0000685{
686 if (su->sa.sa_family == AF_INET)
687 {
688 struct prefix_ipv4 *p;
689
690 p = prefix_ipv4_new ();
691 p->family = AF_INET;
692 p->prefix = su->sin.sin_addr;
693 p->prefixlen = IPV4_MAX_BITLEN;
694 return (struct prefix *) p;
695 }
696#ifdef HAVE_IPV6
697 if (su->sa.sa_family == AF_INET6)
698 {
699 struct prefix_ipv6 *p;
700
701 p = prefix_ipv6_new ();
702 p->family = AF_INET6;
703 p->prefixlen = IPV6_MAX_BITLEN;
704 memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
705 return (struct prefix *) p;
706 }
707#endif /* HAVE_IPV6 */
708 return NULL;
709}
710
David Lamparter17e52062010-02-02 20:16:35 +0100711void
712prefix2sockunion (const struct prefix *p, union sockunion *su)
713{
714 memset (su, 0, sizeof (*su));
715
716 su->sa.sa_family = p->family;
717 if (p->family == AF_INET)
718 su->sin.sin_addr = p->u.prefix4;
719#ifdef HAVE_IPV6
720 if (p->family == AF_INET6)
721 memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
722#endif /* HAVE_IPV6 */
723}
724
paul718e3742002-12-13 20:15:29 +0000725int
hassob04c6992004-10-04 19:10:31 +0000726prefix_blen (const struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000727{
728 switch (p->family)
729 {
730 case AF_INET:
731 return IPV4_MAX_BYTELEN;
732 break;
733#ifdef HAVE_IPV6
734 case AF_INET6:
735 return IPV6_MAX_BYTELEN;
736 break;
737#endif /* HAVE_IPV6 */
738 }
739 return 0;
740}
741
742/* Generic function for conversion string to struct prefix. */
743int
hassob04c6992004-10-04 19:10:31 +0000744str2prefix (const char *str, struct prefix *p)
paul718e3742002-12-13 20:15:29 +0000745{
746 int ret;
747
748 /* First we try to convert string to struct prefix_ipv4. */
749 ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
750 if (ret)
751 return ret;
752
753#ifdef HAVE_IPV6
754 /* Next we try to convert string to struct prefix_ipv6. */
755 ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
756 if (ret)
757 return ret;
758#endif /* HAVE_IPV6 */
759
760 return 0;
761}
762
763int
hassob04c6992004-10-04 19:10:31 +0000764prefix2str (const struct prefix *p, char *str, int size)
paul718e3742002-12-13 20:15:29 +0000765{
766 char buf[BUFSIZ];
767
768 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
769 snprintf (str, size, "%s/%d", buf, p->prefixlen);
770 return 0;
771}
772
773struct prefix *
774prefix_new ()
775{
776 struct prefix *p;
777
778 p = XCALLOC (MTYPE_PREFIX, sizeof *p);
779 return p;
780}
781
782/* Free prefix structure. */
783void
784prefix_free (struct prefix *p)
785{
786 XFREE (MTYPE_PREFIX, p);
787}
788
789/* Utility function. Check the string only contains digit
hassob04c6992004-10-04 19:10:31 +0000790 * character.
791 * FIXME str.[c|h] would be better place for this function. */
paul718e3742002-12-13 20:15:29 +0000792int
hassob04c6992004-10-04 19:10:31 +0000793all_digit (const char *str)
paul718e3742002-12-13 20:15:29 +0000794{
795 for (; *str != '\0'; str++)
796 if (!isdigit ((int) *str))
797 return 0;
798 return 1;
799}
800
801/* Utility function to convert ipv4 prefixes to Classful prefixes */
802void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
803{
804
805 u_int32_t destination;
806
807 destination = ntohl (p->prefix.s_addr);
808
hasso3fb9cd62004-10-19 19:44:43 +0000809 if (p->prefixlen == IPV4_MAX_PREFIXLEN);
paul718e3742002-12-13 20:15:29 +0000810 /* do nothing for host routes */
811 else if (IN_CLASSC (destination))
812 {
813 p->prefixlen=24;
814 apply_mask_ipv4(p);
815 }
816 else if (IN_CLASSB(destination))
817 {
818 p->prefixlen=16;
819 apply_mask_ipv4(p);
820 }
821 else
822 {
823 p->prefixlen=8;
824 apply_mask_ipv4(p);
825 }
826}
827
hasso3fb9cd62004-10-19 19:44:43 +0000828in_addr_t
829ipv4_network_addr (in_addr_t hostaddr, int masklen)
830{
831 struct in_addr mask;
832
833 masklen2ip (masklen, &mask);
834 return hostaddr & mask.s_addr;
835}
836
837in_addr_t
838ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
839{
840 struct in_addr mask;
841
842 masklen2ip (masklen, &mask);
843 return (masklen != IPV4_MAX_PREFIXLEN-1) ?
844 /* normal case */
845 (hostaddr | ~mask.s_addr) :
846 /* special case for /31 */
847 (hostaddr ^ ~mask.s_addr);
848}
849
paul718e3742002-12-13 20:15:29 +0000850/* 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" */
853int
hassob04c6992004-10-04 19:10:31 +0000854netmask_str2prefix_str (const char *net_str, const char *mask_str,
855 char *prefix_str)
paul718e3742002-12-13 20:15:29 +0000856{
857 struct in_addr network;
858 struct in_addr mask;
859 u_char prefixlen;
860 u_int32_t destination;
861 int ret;
862
863 ret = inet_aton (net_str, &network);
864 if (! ret)
865 return 0;
866
867 if (mask_str)
868 {
869 ret = inet_aton (mask_str, &mask);
870 if (! ret)
871 return 0;
872
873 prefixlen = ip_masklen (mask);
874 }
875 else
876 {
877 destination = ntohl (network.s_addr);
878
879 if (network.s_addr == 0)
880 prefixlen = 0;
881 else if (IN_CLASSC (destination))
882 prefixlen = 24;
883 else if (IN_CLASSB (destination))
884 prefixlen = 16;
885 else if (IN_CLASSA (destination))
886 prefixlen = 8;
887 else
888 return 0;
889 }
890
891 sprintf (prefix_str, "%s/%d", net_str, prefixlen);
892
893 return 1;
894}
895
hasso59209902005-04-05 14:36:49 +0000896#ifdef HAVE_IPV6
897/* Utility function for making IPv6 address string. */
898const char *
hasso3a2ce6a2005-04-08 01:30:51 +0000899inet6_ntoa (struct in6_addr addr)
hasso59209902005-04-05 14:36:49 +0000900{
901 static char buf[INET6_ADDRSTRLEN];
902
hasso3a2ce6a2005-04-08 01:30:51 +0000903 inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
hasso59209902005-04-05 14:36:49 +0000904 return buf;
905}
906#endif /* HAVE_IPV6 */