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