modules_s/permissions/ip_tree.h

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