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