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