00001 /* $Id$ 00002 * 00003 * Copyright (C) 2008 iptelorg GmbH 00004 * 00005 * This file is part of ser, a free SIP server. 00006 * 00007 * ser is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version 00011 * 00012 * For a license to use the ser software under conditions 00013 * other than those described here, or to purchase support for this 00014 * software, please contact iptel.org by e-mail at the following addresses: 00015 * info@iptel.org 00016 * 00017 * ser is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU General Public License 00023 * along with this program; if not, write to the Free Software 00024 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00025 * 00026 */ 00027 00028 #ifndef _IP_TREE_H_ 00029 #define _IP_TREE_H_ 1 00030 00031 #include <stdio.h> 00032 #include "../../sr_module.h" 00033 #include "../../dprint.h" 00034 #include "../../ip_addr.h" 00035 #include "../../error.h" 00036 #include "../../mem/mem.h" 00037 #include "../../trim.h" 00038 #include "../../ut.h" 00039 00040 /* 00041 Implements algorithm for testing if particular address is in a iP adrress set. 00042 IP adresses may also describe a subnetwork, i.e. only prefix is valuable and trailing part 00043 of address has no effect for decision. The algorithm is common, both IPv4 and IPv6 00044 are supported. 00045 00046 Reduce(match)/decide(fork) algorithm is applied to minimize memory consumption and looping. 00047 As many bits as possible are matched in leaf (longest prefix match) . If does not match "match_bit_num" then IP is not in set 00048 otherwise next bit decides what is next leaf and matching goes on. 00049 If there is not next leaf then algorithm is over (it's subnet address or special case 00050 particular IP address, in this case address is matched completly). 00051 00052 Examples of ip tree {prefix_match_len, prefix_match, next}: 00053 00054 0.0.0.0/0, i.e. all addresses 00055 {0, {}, {NULL, NULL}} 00056 00057 128.0.0.0/1 00058 {1, {0x80}, {NULL, NULL}} 00059 00060 127.0.1.0/24 00061 {24, {0x7F, 0x00, 0x01}, {NULL, NULL}} 00062 00063 127.0.1.0/24, 127.0.2.0/24 00064 01111111.00000000.00000001.00000000 01111111.00000000.00000010.00000000 00065 {22, {0x7F, 0x00, 0x00}, { 00066 {1, {0x80}, {NULL, NULL}}, 00067 {1, {0x00}, {NULL, NULL}} 00068 } 00069 } 00070 00071 127.0.0.0/32, 127.0.0.1/32 00072 {31, {0x7F, 0x00, 0x00, 0x00}, {NULL, NULL}} 00073 00074 192.168.5.64/26, 192.168.5.15/32, 10.0.0.0/8 00075 11000000.10101000.00000101.01-000000 11000000.10101000.00000101.00001111 00001010-00000000.00000000.00000000 00076 00077 {0, {}, { 00078 {7, {00010100}, {NULL, NULL}}, 00079 {24, {10000001,01010000,00001010}, { 00080 {6, {00111100}, {NULL, NULL}}, 00081 {0, {}, {NULL, NULL}} 00082 }} 00083 }} 00084 00085 00086 */ 00087 00088 struct ip_tree_leaf { 00089 unsigned int prefix_match_len; /* next prefix_match_len must be equal to next bit in IP address being compared */ 00090 struct ip_tree_leaf *next[2]; /* tree goes on in leaf based on first bit following prefix_match, if next[0] && next[1] are null then IP matches - it's subnet address */ 00091 unsigned char prefix_match[0]; /* match_bits div 8 + 1, the same representation as ip address */ 00092 }; 00093 00094 struct ip_tree_find { 00095 struct ip_tree_leaf *leaf; 00096 unsigned int leaf_prefix_match_len; 00097 unsigned char *leaf_prefix_match; 00098 unsigned char leaf_prefix_match_mask; 00099 unsigned char *ip; 00100 unsigned int ip_len; 00101 unsigned char ip_mask; 00102 }; 00103 00104 #define IP_TREE_FIND_NOT_FOUND 0 00105 #define IP_TREE_FIND_FOUND 1 00106 #define IP_TREE_FIND_FOUND_UPPER_SET 2 00107 00108 extern void ip_tree_init(struct ip_tree_leaf **tree); 00109 extern void ip_tree_destroy(struct ip_tree_leaf **tree, int leaves_only, int use_shm); 00110 extern int ip_tree_find_ip(struct ip_tree_leaf *tree, unsigned char *ip, unsigned int ip_len, struct ip_tree_find *h); 00111 extern int ip_tree_add_ip(struct ip_tree_leaf **tree, unsigned char *ip, unsigned int ip_len, int use_shm); 00112 extern void ip_tree_print(FILE *stream, struct ip_tree_leaf *tree, unsigned int indent); 00113 extern str ip_tree_mask_to_str(unsigned char *pm, unsigned int len); 00114 #endif
1.7.1