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