Annotation of embedaddon/quagga/lib/prefix.c, revision 1.1.1.3
1.1 misho 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"
1.1.1.3 ! misho 30:
1.1 misho 31: /* Maskbit. */
32: static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
33: 0xf8, 0xfc, 0xfe, 0xff};
34:
1.1.1.2 misho 35: static const struct in6_addr maskbytes6[] =
36: {
37: /* /0 */ { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
38: /* /1 */ { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
39: /* /2 */ { { { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
40: /* /3 */ { { { 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
41: /* /4 */ { { { 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
42: /* /5 */ { { { 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
43: /* /6 */ { { { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
44: /* /7 */ { { { 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
45: /* /8 */ { { { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
46: /* /9 */ { { { 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
47: /* /10 */ { { { 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
48: /* /11 */ { { { 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
49: /* /12 */ { { { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
50: /* /13 */ { { { 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
51: /* /14 */ { { { 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
52: /* /15 */ { { { 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
53: /* /16 */ { { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
54: /* /17 */ { { { 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
55: /* /18 */ { { { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
56: /* /19 */ { { { 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
57: /* /20 */ { { { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
58: /* /21 */ { { { 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
59: /* /22 */ { { { 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
60: /* /23 */ { { { 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
61: /* /24 */ { { { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
62: /* /25 */ { { { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
63: /* /26 */ { { { 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
64: /* /27 */ { { { 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
65: /* /28 */ { { { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
66: /* /29 */ { { { 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
67: /* /30 */ { { { 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
68: /* /31 */ { { { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
69: /* /32 */ { { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
70: /* /33 */ { { { 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
71: /* /34 */ { { { 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
72: /* /35 */ { { { 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
73: /* /36 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
74: /* /37 */ { { { 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
75: /* /38 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
76: /* /39 */ { { { 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
77: /* /40 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
78: /* /41 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
79: /* /42 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
80: /* /43 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
81: /* /44 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
82: /* /45 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
83: /* /46 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
84: /* /47 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
85: /* /48 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
86: /* /49 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
87: /* /50 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
88: /* /51 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
89: /* /52 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
90: /* /53 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
91: /* /54 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
92: /* /55 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
93: /* /56 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
94: /* /57 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
95: /* /58 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
96: /* /59 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
97: /* /60 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
98: /* /61 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
99: /* /62 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
100: /* /63 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
101: /* /64 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
102: /* /65 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
103: /* /66 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
104: /* /67 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
105: /* /68 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
106: /* /69 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
107: /* /70 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
108: /* /71 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
109: /* /72 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
110: /* /73 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
111: /* /74 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
112: /* /75 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
113: /* /76 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
114: /* /77 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
115: /* /78 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
116: /* /79 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
117: /* /80 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
118: /* /81 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
119: /* /82 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
120: /* /83 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
121: /* /84 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
122: /* /85 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
123: /* /86 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
124: /* /87 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
125: /* /88 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
126: /* /89 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00 } } },
127: /* /90 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00 } } },
128: /* /91 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00 } } },
129: /* /92 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } } },
130: /* /93 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00 } } },
131: /* /94 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00 } } },
132: /* /95 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 } } },
133: /* /96 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
134: /* /97 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 } } },
135: /* /98 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00 } } },
136: /* /99 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00 } } },
137: /* /100 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 } } },
138: /* /101 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00 } } },
139: /* /102 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00 } } },
140: /* /103 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00 } } },
141: /* /104 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } } },
142: /* /105 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 } } },
143: /* /106 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00 } } },
144: /* /107 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00 } } },
145: /* /108 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } } },
146: /* /109 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00 } } },
147: /* /110 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00 } } },
148: /* /111 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00 } } },
149: /* /112 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
150: /* /113 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00 } } },
151: /* /114 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 } } },
152: /* /115 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00 } } },
153: /* /116 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 } } },
154: /* /117 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00 } } },
155: /* /118 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00 } } },
156: /* /119 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00 } } },
157: /* /120 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } } },
158: /* /121 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 } } },
159: /* /122 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 } } },
160: /* /123 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0 } } },
161: /* /124 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 } } },
162: /* /125 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8 } } },
163: /* /126 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc } } },
164: /* /127 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe } } },
165: /* /128 */ { { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }
166: };
167:
1.1 misho 168: /* Number of bits in prefix type. */
169: #ifndef PNBBY
170: #define PNBBY 8
171: #endif /* PNBBY */
172:
173: #define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
174:
1.1.1.2 misho 175: unsigned int
176: prefix_bit (const u_char *prefix, const u_char prefixlen)
177: {
178: unsigned int offset = prefixlen / 8;
179: unsigned int shift = 7 - (prefixlen % 8);
180:
181: return (prefix[offset] >> shift) & 1;
182: }
183:
184: unsigned int
185: prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
186: {
187: return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
188: }
1.1.1.3 ! misho 189:
! 190: int
! 191: str2family(const char *string)
! 192: {
! 193: if (!strcmp("ipv4", string))
! 194: return AF_INET;
! 195: else if (!strcmp("ipv6", string))
! 196: return AF_INET6;
! 197: else
! 198: return -1;
! 199: }
! 200:
1.1 misho 201: /* Address Famiy Identifier to Address Family converter. */
202: int
203: afi2family (afi_t afi)
204: {
205: if (afi == AFI_IP)
206: return AF_INET;
207: #ifdef HAVE_IPV6
208: else if (afi == AFI_IP6)
209: return AF_INET6;
210: #endif /* HAVE_IPV6 */
211: return 0;
212: }
213:
214: afi_t
215: family2afi (int family)
216: {
217: if (family == AF_INET)
218: return AFI_IP;
219: #ifdef HAVE_IPV6
220: else if (family == AF_INET6)
221: return AFI_IP6;
222: #endif /* HAVE_IPV6 */
223: return 0;
224: }
225:
1.1.1.3 ! misho 226: const char *
! 227: safi2str(safi_t safi)
! 228: {
! 229: switch (safi) {
! 230: case SAFI_UNICAST:
! 231: return "unicast";
! 232: case SAFI_MULTICAST:
! 233: return "multicast";
! 234: case SAFI_ENCAP:
! 235: return "encap";
! 236: case SAFI_MPLS_VPN:
! 237: return "vpn";
! 238: }
! 239: return NULL;
! 240: }
! 241:
1.1 misho 242: /* If n includes p prefix then return 1 else return 0. */
243: int
244: prefix_match (const struct prefix *n, const struct prefix *p)
245: {
246: int offset;
247: int shift;
248: const u_char *np, *pp;
249:
250: /* If n's prefix is longer than p's one return 0. */
251: if (n->prefixlen > p->prefixlen)
252: return 0;
253:
254: /* Set both prefix's head pointer. */
255: np = (const u_char *)&n->u.prefix;
256: pp = (const u_char *)&p->u.prefix;
257:
258: offset = n->prefixlen / PNBBY;
259: shift = n->prefixlen % PNBBY;
260:
261: if (shift)
262: if (maskbit[shift] & (np[offset] ^ pp[offset]))
263: return 0;
264:
265: while (offset--)
266: if (np[offset] != pp[offset])
267: return 0;
268: return 1;
269: }
270:
271: /* Copy prefix from src to dest. */
272: void
273: prefix_copy (struct prefix *dest, const struct prefix *src)
274: {
275: dest->family = src->family;
276: dest->prefixlen = src->prefixlen;
277:
278: if (src->family == AF_INET)
279: dest->u.prefix4 = src->u.prefix4;
280: #ifdef HAVE_IPV6
281: else if (src->family == AF_INET6)
282: dest->u.prefix6 = src->u.prefix6;
283: #endif /* HAVE_IPV6 */
284: else if (src->family == AF_UNSPEC)
285: {
286: dest->u.lp.id = src->u.lp.id;
287: dest->u.lp.adv_router = src->u.lp.adv_router;
288: }
289: else
290: {
291: zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d",
292: src->family);
293: assert (0);
294: }
295: }
296:
297: /*
298: * Return 1 if the address/netmask contained in the prefix structure
299: * is the same, and else return 0. For this routine, 'same' requires
300: * that not only the prefix length and the network part be the same,
301: * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
302: * the same. Note that this routine has the same return value sense
303: * as '==' (which is different from prefix_cmp).
304: */
305: int
306: prefix_same (const struct prefix *p1, const struct prefix *p2)
307: {
308: if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
309: {
310: if (p1->family == AF_INET)
1.1.1.2 misho 311: if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr))
1.1 misho 312: return 1;
313: #ifdef HAVE_IPV6
314: if (p1->family == AF_INET6 )
1.1.1.2 misho 315: if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr))
1.1 misho 316: return 1;
317: #endif /* HAVE_IPV6 */
318: }
319: return 0;
320: }
321:
322: /*
323: * Return 0 if the network prefixes represented by the struct prefix
324: * arguments are the same prefix, and 1 otherwise. Network prefixes
325: * are considered the same if the prefix lengths are equal and the
326: * network parts are the same. Host bits (which are considered masked
327: * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
328: * 10.0.0.2/8 are considered equivalent by this routine. Note that
329: * this routine has the same return sense as strcmp (which is different
330: * from prefix_same).
331: */
332: int
333: prefix_cmp (const struct prefix *p1, const struct prefix *p2)
334: {
335: int offset;
336: int shift;
337:
338: /* Set both prefix's head pointer. */
339: const u_char *pp1 = (const u_char *)&p1->u.prefix;
340: const u_char *pp2 = (const u_char *)&p2->u.prefix;
341:
342: if (p1->family != p2->family || p1->prefixlen != p2->prefixlen)
343: return 1;
344:
1.1.1.2 misho 345: offset = p1->prefixlen / PNBBY;
346: shift = p1->prefixlen % PNBBY;
1.1 misho 347:
348: if (shift)
349: if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
350: return 1;
351:
352: while (offset--)
353: if (pp1[offset] != pp2[offset])
354: return 1;
355:
356: return 0;
357: }
358:
1.1.1.2 misho 359: /*
360: * Count the number of common bits in 2 prefixes. The prefix length is
361: * ignored for this function; the whole prefix is compared. If the prefix
362: * address families don't match, return -1; otherwise the return value is
363: * in range 0 ... maximum prefix length for the address family.
364: */
365: int
366: prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
367: {
368: int pos, bit;
369: int length = 0;
370: u_char xor;
371:
372: /* Set both prefix's head pointer. */
373: const u_char *pp1 = (const u_char *)&p1->u.prefix;
374: const u_char *pp2 = (const u_char *)&p2->u.prefix;
375:
376: if (p1->family == AF_INET)
377: length = IPV4_MAX_BYTELEN;
378: #ifdef HAVE_IPV6
379: if (p1->family == AF_INET6)
380: length = IPV6_MAX_BYTELEN;
381: #endif
382: if (p1->family != p2->family || !length)
383: return -1;
384:
385: for (pos = 0; pos < length; pos++)
386: if (pp1[pos] != pp2[pos])
387: break;
388: if (pos == length)
389: return pos * 8;
390:
391: xor = pp1[pos] ^ pp2[pos];
392: for (bit = 0; bit < 8; bit++)
393: if (xor & (1 << (7 - bit)))
394: break;
395:
396: return pos * 8 + bit;
397: }
398:
1.1 misho 399: /* Return prefix family type string. */
400: const char *
401: prefix_family_str (const struct prefix *p)
402: {
403: if (p->family == AF_INET)
404: return "inet";
405: #ifdef HAVE_IPV6
406: if (p->family == AF_INET6)
407: return "inet6";
408: #endif /* HAVE_IPV6 */
409: return "unspec";
410: }
411:
412: /* Allocate new prefix_ipv4 structure. */
413: struct prefix_ipv4 *
414: prefix_ipv4_new ()
415: {
416: struct prefix_ipv4 *p;
417:
418: /* Call prefix_new to allocate a full-size struct prefix to avoid problems
419: where the struct prefix_ipv4 is cast to struct prefix and unallocated
420: bytes were being referenced (e.g. in structure assignments). */
421: p = (struct prefix_ipv4 *)prefix_new();
422: p->family = AF_INET;
423: return p;
424: }
425:
426: /* Free prefix_ipv4 structure. */
427: void
428: prefix_ipv4_free (struct prefix_ipv4 *p)
429: {
430: prefix_free((struct prefix *)p);
431: }
432:
433: /* When string format is invalid return 0. */
434: int
435: str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
436: {
437: int ret;
438: int plen;
439: char *pnt;
440: char *cp;
441:
442: /* Find slash inside string. */
443: pnt = strchr (str, '/');
444:
445: /* String doesn't contail slash. */
446: if (pnt == NULL)
447: {
448: /* Convert string to prefix. */
449: ret = inet_aton (str, &p->prefix);
450: if (ret == 0)
451: return 0;
452:
453: /* If address doesn't contain slash we assume it host address. */
454: p->family = AF_INET;
455: p->prefixlen = IPV4_MAX_BITLEN;
456:
457: return ret;
458: }
459: else
460: {
461: cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
462: strncpy (cp, str, pnt - str);
463: *(cp + (pnt - str)) = '\0';
464: ret = inet_aton (cp, &p->prefix);
465: XFREE (MTYPE_TMP, cp);
466:
467: /* Get prefix length. */
468: plen = (u_char) atoi (++pnt);
469: if (plen > IPV4_MAX_PREFIXLEN)
470: return 0;
471:
472: p->family = AF_INET;
473: p->prefixlen = plen;
474: }
475:
476: return ret;
477: }
478:
1.1.1.2 misho 479: /* Convert masklen into IP address's netmask (network byte order). */
1.1 misho 480: void
1.1.1.2 misho 481: masklen2ip (const int masklen, struct in_addr *netmask)
1.1 misho 482: {
1.1.1.2 misho 483: assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
1.1 misho 484:
1.1.1.2 misho 485: /* left shift is only defined for less than the size of the type.
486: * we unconditionally use long long in case the target platform
487: * has defined behaviour for << 32 (or has a 64-bit left shift) */
1.1 misho 488:
1.1.1.2 misho 489: if (sizeof(unsigned long long) > 4)
490: netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
491: else
492: netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
1.1 misho 493: }
494:
495: /* Convert IP address's netmask into integer. We assume netmask is
496: sequential one. Argument netmask should be network byte order. */
497: u_char
498: ip_masklen (struct in_addr netmask)
499: {
1.1.1.2 misho 500: uint32_t tmp = ~ntohl(netmask.s_addr);
501: if (tmp)
502: /* clz: count leading zeroes. sadly, the behaviour of this builtin
503: * is undefined for a 0 argument, even though most CPUs give 32 */
504: return __builtin_clz(tmp);
505: else
506: return 32;
1.1 misho 507: }
508:
1.1.1.2 misho 509: /* Apply mask to IPv4 prefix (network byte order). */
1.1 misho 510: void
511: apply_mask_ipv4 (struct prefix_ipv4 *p)
512: {
1.1.1.2 misho 513: struct in_addr mask;
514: masklen2ip(p->prefixlen, &mask);
515: p->prefix.s_addr &= mask.s_addr;
1.1 misho 516: }
517:
518: /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
519: int
520: prefix_ipv4_any (const struct prefix_ipv4 *p)
521: {
522: return (p->prefix.s_addr == 0 && p->prefixlen == 0);
523: }
1.1.1.3 ! misho 524:
1.1 misho 525: #ifdef HAVE_IPV6
526:
527: /* Allocate a new ip version 6 route */
528: struct prefix_ipv6 *
529: prefix_ipv6_new (void)
530: {
531: struct prefix_ipv6 *p;
532:
533: /* Allocate a full-size struct prefix to avoid problems with structure
534: size mismatches. */
535: p = (struct prefix_ipv6 *)prefix_new();
536: p->family = AF_INET6;
537: return p;
538: }
539:
540: /* Free prefix for IPv6. */
541: void
542: prefix_ipv6_free (struct prefix_ipv6 *p)
543: {
544: prefix_free((struct prefix *)p);
545: }
546:
547: /* If given string is valid return pin6 else return NULL */
548: int
549: str2prefix_ipv6 (const char *str, struct prefix_ipv6 *p)
550: {
551: char *pnt;
552: char *cp;
553: int ret;
554:
555: pnt = strchr (str, '/');
556:
557: /* If string doesn't contain `/' treat it as host route. */
558: if (pnt == NULL)
559: {
560: ret = inet_pton (AF_INET6, str, &p->prefix);
561: if (ret == 0)
562: return 0;
563: p->prefixlen = IPV6_MAX_BITLEN;
564: }
565: else
566: {
567: int plen;
568:
569: cp = XMALLOC (0, (pnt - str) + 1);
570: strncpy (cp, str, pnt - str);
571: *(cp + (pnt - str)) = '\0';
572: ret = inet_pton (AF_INET6, cp, &p->prefix);
573: free (cp);
574: if (ret == 0)
575: return 0;
576: plen = (u_char) atoi (++pnt);
1.1.1.2 misho 577: if (plen > IPV6_MAX_BITLEN)
1.1 misho 578: return 0;
579: p->prefixlen = plen;
580: }
581: p->family = AF_INET6;
582:
583: return ret;
584: }
585:
586: /* Convert struct in6_addr netmask into integer.
587: * FIXME return u_char as ip_maskleni() does. */
588: int
589: ip6_masklen (struct in6_addr netmask)
590: {
591: int len = 0;
592: unsigned char val;
593: unsigned char *pnt;
594:
595: pnt = (unsigned char *) & netmask;
596:
1.1.1.2 misho 597: while ((*pnt == 0xff) && len < IPV6_MAX_BITLEN)
1.1 misho 598: {
599: len += 8;
600: pnt++;
601: }
602:
1.1.1.2 misho 603: if (len < IPV6_MAX_BITLEN)
1.1 misho 604: {
605: val = *pnt;
606: while (val)
607: {
608: len++;
609: val <<= 1;
610: }
611: }
612: return len;
613: }
614:
615: void
1.1.1.2 misho 616: masklen2ip6 (const int masklen, struct in6_addr *netmask)
1.1 misho 617: {
1.1.1.2 misho 618: assert (masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
619: memcpy (netmask, maskbytes6 + masklen, sizeof (struct in6_addr));
1.1 misho 620: }
621:
622: void
623: apply_mask_ipv6 (struct prefix_ipv6 *p)
624: {
625: u_char *pnt;
626: int index;
627: int offset;
628:
629: index = p->prefixlen / 8;
630:
631: if (index < 16)
632: {
633: pnt = (u_char *) &p->prefix;
634: offset = p->prefixlen % 8;
635:
636: pnt[index] &= maskbit[offset];
637: index++;
638:
639: while (index < 16)
640: pnt[index++] = 0;
641: }
642: }
643:
644: void
645: str2in6_addr (const char *str, struct in6_addr *addr)
646: {
647: int i;
648: unsigned int x;
649:
650: /* %x must point to unsinged int */
651: for (i = 0; i < 16; i++)
652: {
653: sscanf (str + (i * 2), "%02x", &x);
654: addr->s6_addr[i] = x & 0xff;
655: }
656: }
657: #endif /* HAVE_IPV6 */
658:
659: void
660: apply_mask (struct prefix *p)
661: {
662: switch (p->family)
663: {
664: case AF_INET:
665: apply_mask_ipv4 ((struct prefix_ipv4 *)p);
666: break;
667: #ifdef HAVE_IPV6
668: case AF_INET6:
669: apply_mask_ipv6 ((struct prefix_ipv6 *)p);
670: break;
671: #endif /* HAVE_IPV6 */
672: default:
673: break;
674: }
675: return;
676: }
677:
678: /* Utility function of convert between struct prefix <=> union sockunion.
679: * FIXME This function isn't used anywhere. */
680: struct prefix *
681: sockunion2prefix (const union sockunion *dest,
682: const union sockunion *mask)
683: {
684: if (dest->sa.sa_family == AF_INET)
685: {
686: struct prefix_ipv4 *p;
687:
688: p = prefix_ipv4_new ();
689: p->family = AF_INET;
690: p->prefix = dest->sin.sin_addr;
691: p->prefixlen = ip_masklen (mask->sin.sin_addr);
692: return (struct prefix *) p;
693: }
694: #ifdef HAVE_IPV6
695: if (dest->sa.sa_family == AF_INET6)
696: {
697: struct prefix_ipv6 *p;
698:
699: p = prefix_ipv6_new ();
700: p->family = AF_INET6;
701: p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
702: memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
703: return (struct prefix *) p;
704: }
705: #endif /* HAVE_IPV6 */
706: return NULL;
707: }
708:
709: /* Utility function of convert between struct prefix <=> union sockunion. */
710: struct prefix *
1.1.1.3 ! misho 711: sockunion2hostprefix (const union sockunion *su, struct prefix *prefix)
1.1 misho 712: {
713: if (su->sa.sa_family == AF_INET)
714: {
715: struct prefix_ipv4 *p;
716:
1.1.1.3 ! misho 717: p = prefix ? (struct prefix_ipv4 *) prefix : prefix_ipv4_new ();
1.1 misho 718: p->family = AF_INET;
719: p->prefix = su->sin.sin_addr;
720: p->prefixlen = IPV4_MAX_BITLEN;
721: return (struct prefix *) p;
722: }
723: #ifdef HAVE_IPV6
724: if (su->sa.sa_family == AF_INET6)
725: {
726: struct prefix_ipv6 *p;
727:
1.1.1.3 ! misho 728: p = prefix ? (struct prefix_ipv6 *) prefix : prefix_ipv6_new ();
1.1 misho 729: p->family = AF_INET6;
730: p->prefixlen = IPV6_MAX_BITLEN;
731: memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
732: return (struct prefix *) p;
733: }
734: #endif /* HAVE_IPV6 */
735: return NULL;
736: }
737:
1.1.1.2 misho 738: void
739: prefix2sockunion (const struct prefix *p, union sockunion *su)
740: {
741: memset (su, 0, sizeof (*su));
742:
743: su->sa.sa_family = p->family;
744: if (p->family == AF_INET)
745: su->sin.sin_addr = p->u.prefix4;
746: #ifdef HAVE_IPV6
747: if (p->family == AF_INET6)
748: memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
749: #endif /* HAVE_IPV6 */
750: }
751:
1.1 misho 752: int
753: prefix_blen (const struct prefix *p)
754: {
755: switch (p->family)
756: {
757: case AF_INET:
758: return IPV4_MAX_BYTELEN;
759: break;
760: #ifdef HAVE_IPV6
761: case AF_INET6:
762: return IPV6_MAX_BYTELEN;
763: break;
764: #endif /* HAVE_IPV6 */
765: }
766: return 0;
767: }
768:
769: /* Generic function for conversion string to struct prefix. */
770: int
771: str2prefix (const char *str, struct prefix *p)
772: {
773: int ret;
774:
775: /* First we try to convert string to struct prefix_ipv4. */
776: ret = str2prefix_ipv4 (str, (struct prefix_ipv4 *) p);
777: if (ret)
778: return ret;
779:
780: #ifdef HAVE_IPV6
781: /* Next we try to convert string to struct prefix_ipv6. */
782: ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p);
783: if (ret)
784: return ret;
785: #endif /* HAVE_IPV6 */
786:
787: return 0;
788: }
789:
1.1.1.3 ! misho 790: const char *
! 791: prefix2str (union prefix46constptr pu, char *str, int size)
1.1 misho 792: {
1.1.1.3 ! misho 793: const struct prefix *p = pu.p;
1.1 misho 794: char buf[BUFSIZ];
795:
796: inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
797: snprintf (str, size, "%s/%d", buf, p->prefixlen);
1.1.1.3 ! misho 798: return str;
1.1 misho 799: }
800:
801: struct prefix *
802: prefix_new ()
803: {
804: struct prefix *p;
805:
806: p = XCALLOC (MTYPE_PREFIX, sizeof *p);
807: return p;
808: }
809:
810: /* Free prefix structure. */
811: void
812: prefix_free (struct prefix *p)
813: {
814: XFREE (MTYPE_PREFIX, p);
815: }
816:
817: /* Utility function. Check the string only contains digit
818: * character.
819: * FIXME str.[c|h] would be better place for this function. */
820: int
821: all_digit (const char *str)
822: {
823: for (; *str != '\0'; str++)
824: if (!isdigit ((int) *str))
825: return 0;
826: return 1;
827: }
828:
829: /* Utility function to convert ipv4 prefixes to Classful prefixes */
830: void apply_classful_mask_ipv4 (struct prefix_ipv4 *p)
831: {
832:
833: u_int32_t destination;
834:
835: destination = ntohl (p->prefix.s_addr);
836:
837: if (p->prefixlen == IPV4_MAX_PREFIXLEN);
838: /* do nothing for host routes */
839: else if (IN_CLASSC (destination))
840: {
841: p->prefixlen=24;
842: apply_mask_ipv4(p);
843: }
844: else if (IN_CLASSB(destination))
845: {
846: p->prefixlen=16;
847: apply_mask_ipv4(p);
848: }
849: else
850: {
851: p->prefixlen=8;
852: apply_mask_ipv4(p);
853: }
854: }
855:
856: in_addr_t
857: ipv4_network_addr (in_addr_t hostaddr, int masklen)
858: {
859: struct in_addr mask;
860:
861: masklen2ip (masklen, &mask);
862: return hostaddr & mask.s_addr;
863: }
864:
865: in_addr_t
866: ipv4_broadcast_addr (in_addr_t hostaddr, int masklen)
867: {
868: struct in_addr mask;
869:
870: masklen2ip (masklen, &mask);
871: return (masklen != IPV4_MAX_PREFIXLEN-1) ?
872: /* normal case */
873: (hostaddr | ~mask.s_addr) :
874: /* special case for /31 */
875: (hostaddr ^ ~mask.s_addr);
876: }
877:
878: /* Utility function to convert ipv4 netmask to prefixes
879: ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
880: ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
881: int
882: netmask_str2prefix_str (const char *net_str, const char *mask_str,
883: char *prefix_str)
884: {
885: struct in_addr network;
886: struct in_addr mask;
887: u_char prefixlen;
888: u_int32_t destination;
889: int ret;
890:
891: ret = inet_aton (net_str, &network);
892: if (! ret)
893: return 0;
894:
895: if (mask_str)
896: {
897: ret = inet_aton (mask_str, &mask);
898: if (! ret)
899: return 0;
900:
901: prefixlen = ip_masklen (mask);
902: }
903: else
904: {
905: destination = ntohl (network.s_addr);
906:
907: if (network.s_addr == 0)
908: prefixlen = 0;
909: else if (IN_CLASSC (destination))
910: prefixlen = 24;
911: else if (IN_CLASSB (destination))
912: prefixlen = 16;
913: else if (IN_CLASSA (destination))
914: prefixlen = 8;
915: else
916: return 0;
917: }
918:
919: sprintf (prefix_str, "%s/%d", net_str, prefixlen);
920:
921: return 1;
922: }
923:
924: #ifdef HAVE_IPV6
925: /* Utility function for making IPv6 address string. */
926: const char *
927: inet6_ntoa (struct in6_addr addr)
928: {
929: static char buf[INET6_ADDRSTRLEN];
930:
931: inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN);
932: return buf;
933: }
934: #endif /* HAVE_IPV6 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>