|
Packit |
284210 |
/*
|
|
Packit |
284210 |
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
Packit |
284210 |
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* You may not use this file except in compliance with
|
|
Packit |
284210 |
* the License. You may obtain a copy of the License at
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
284210 |
*
|
|
Packit |
284210 |
* If any of the files related to licensing are missing or if you have any
|
|
Packit |
284210 |
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
Packit |
284210 |
* directly using the email address security@modsecurity.org.
|
|
Packit |
284210 |
*/
|
|
Packit |
284210 |
|
|
Packit |
284210 |
#include <stdio.h>
|
|
Packit |
284210 |
#include <stdlib.h>
|
|
Packit |
284210 |
#if APR_HAVE_STDINT_H
|
|
Packit |
284210 |
#include <stdint.h>
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
#include <string.h>
|
|
Packit |
284210 |
#if APR_HAVE_NETINET_IN_H
|
|
Packit |
284210 |
#include <netinet/in.h>
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
#if APR_HAVE_ARPA_INET_H
|
|
Packit |
284210 |
#include <arpa/inet.h>
|
|
Packit |
284210 |
#endif
|
|
Packit |
284210 |
#include "apr_lib.h"
|
|
Packit |
284210 |
#include "msc_util.h"
|
|
Packit |
284210 |
#include "msc_tree.h"
|
|
Packit |
284210 |
|
|
Packit |
284210 |
CPTTree *CPTCreateRadixTree(apr_pool_t *pool) {
|
|
Packit |
284210 |
CPTTree *tree = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
tree = apr_palloc(pool, sizeof(CPTTree));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(tree == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(tree, 0, sizeof(CPTTree));
|
|
Packit |
284210 |
tree->pool = pool;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return tree;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void ConvertIPNetmask(unsigned char *buffer, unsigned char netmask, unsigned int ip_bitmask) {
|
|
Packit |
284210 |
int aux = 0, bytes = 0;
|
|
Packit |
284210 |
int mask = 0, mask_bit = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
bytes = ip_bitmask/8;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(aux < bytes) {
|
|
Packit |
284210 |
mask_bit = ((1+aux) * 8);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (mask_bit > netmask) {
|
|
Packit |
284210 |
mask = 0;
|
|
Packit |
284210 |
if ((mask_bit - netmask) < 8) mask = SHIFT_LEFT_MASK(mask_bit - netmask);
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
mask = -1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
buffer[aux] &= mask;
|
|
Packit |
284210 |
aux++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTCreateNode(apr_pool_t *pool) {
|
|
Packit |
284210 |
TreeNode *node = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = apr_palloc(pool, sizeof(TreeNode));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(node, 0, sizeof(TreeNode));
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
CPTData *CPTCreateCPTData(unsigned char netmask, apr_pool_t *pool) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
CPTData *prefix_data = apr_palloc(pool, sizeof(CPTData));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (prefix_data == NULL) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(prefix_data, 0, sizeof(CPTData));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix_data->netmask = netmask;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return prefix_data;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreePrefix *InsertDataPrefix(TreePrefix *prefix, unsigned char *ipdata, unsigned int ip_bitmask,
|
|
Packit |
284210 |
unsigned char netmask, apr_pool_t *pool) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(prefix == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memcpy(prefix->buffer, ipdata, ip_bitmask/8);
|
|
Packit |
284210 |
prefix->bitlen = ip_bitmask;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix->prefix_data = CPTCreateCPTData(netmask, pool);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(prefix->prefix_data == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return prefix;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreePrefix *CPTCreatePrefix(unsigned char *ipdata, unsigned int ip_bitmask,
|
|
Packit |
284210 |
unsigned char netmask, apr_pool_t *pool) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreePrefix *prefix = NULL;
|
|
Packit |
284210 |
int bytes = ip_bitmask/8;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((ip_bitmask % 8 != 0) || (ipdata == NULL)) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix = apr_palloc(pool, sizeof(TreePrefix));
|
|
Packit |
284210 |
if (prefix == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(prefix, 0, sizeof(TreePrefix));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix->buffer = apr_palloc(pool, bytes);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(prefix->buffer == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(prefix->buffer, 0, bytes);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return InsertDataPrefix(prefix, ipdata, ip_bitmask, netmask, pool);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
void CPTAppendToCPTDataList(CPTData *new, CPTData **list) {
|
|
Packit |
284210 |
CPTData *temp = NULL, *prev = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (new == NULL) {
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (list == NULL) {
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prev = *list;
|
|
Packit |
284210 |
temp = *list;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (temp != NULL) {
|
|
Packit |
284210 |
if (new->netmask > temp->netmask)
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
prev = temp;
|
|
Packit |
284210 |
temp = temp->next;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (temp == *list) {
|
|
Packit |
284210 |
new->next = *list;
|
|
Packit |
284210 |
*list = new;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
new->next = prev->next;
|
|
Packit |
284210 |
prev->next = new;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int TreePrefixContainNetmask(TreePrefix *prefix, unsigned char netmask) {
|
|
Packit |
284210 |
CPTData *prefix_data = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (prefix == NULL) {
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix_data = prefix->prefix_data;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (prefix_data != NULL) {
|
|
Packit |
284210 |
if (prefix_data->netmask == netmask)
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
prefix_data = prefix_data->next;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int CheckBitmask(unsigned char netmask, unsigned int ip_bitmask) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
switch(netmask) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
case 0xff:
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
case 0x20:
|
|
Packit |
284210 |
if(ip_bitmask == 0x20)
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
case 0x80:
|
|
Packit |
284210 |
if(ip_bitmask == 0x80)
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTCreateHead(TreePrefix *prefix, TreeNode *node, CPTTree *tree, unsigned char netmask, unsigned int ip_bitmask) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(tree == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(prefix == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node != NULL) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->prefix = prefix;
|
|
Packit |
284210 |
node->bit = prefix->bitlen;
|
|
Packit |
284210 |
tree->head = node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(CheckBitmask(netmask, ip_bitmask))
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->count++;
|
|
Packit |
284210 |
node->netmasks = apr_palloc(tree->pool, (node->count * sizeof(unsigned char)));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node->netmasks)
|
|
Packit |
284210 |
node->netmasks[0] = netmask;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *SetParentNode(TreeNode *node, TreeNode *new_node, CPTTree *tree) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node->parent == NULL)
|
|
Packit |
284210 |
tree->head = new_node;
|
|
Packit |
284210 |
else if (node->parent->right == node)
|
|
Packit |
284210 |
node->parent->right = new_node;
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
node->parent->left = new_node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return new_node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int InsertNetmask(TreeNode *node, TreeNode *parent, TreeNode *new_node,
|
|
Packit |
284210 |
CPTTree *tree, unsigned char netmask, unsigned char bitlen) {
|
|
Packit |
284210 |
int i;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (netmask != NETMASK_256-1 && netmask != NETMASK_128) {
|
|
Packit |
284210 |
if ((netmask != NETMASK_32 || (netmask == NETMASK_32 && bitlen != NETMASK_32))) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = new_node;
|
|
Packit |
284210 |
parent = new_node->parent;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (parent != NULL && netmask < (parent->bit + 1)) {
|
|
Packit |
284210 |
node = parent;
|
|
Packit |
284210 |
parent = parent->parent;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->count++;
|
|
Packit |
284210 |
node->netmasks = apr_palloc(tree->pool, (node->count * sizeof(unsigned char)));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node->netmasks == NULL)
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
if ((node->count-1) == 0) {
|
|
Packit |
284210 |
node->netmasks[0] = netmask;
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->netmasks[node->count - 1] = netmask;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
i = node->count - 2;
|
|
Packit |
284210 |
while (i >= 0) {
|
|
Packit |
284210 |
if (netmask < node->netmasks[i]) {
|
|
Packit |
284210 |
node->netmasks[i + 1] = netmask;
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->netmasks[i + 1] = node->netmasks[i];
|
|
Packit |
284210 |
node->netmasks[i] = netmask;
|
|
Packit |
284210 |
i--;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTAddElement(unsigned char *ipdata, unsigned int ip_bitmask, CPTTree *tree, unsigned char netmask) {
|
|
Packit |
284210 |
unsigned char *buffer = NULL;
|
|
Packit |
284210 |
unsigned char bitlen = 0;
|
|
Packit |
284210 |
int bit_validation = 0, test_bit = 0;
|
|
Packit |
284210 |
int i = 0, j = 0, temp = 0;
|
|
Packit |
284210 |
unsigned int x, y;
|
|
Packit |
284210 |
TreeNode *node = NULL, *new_node = NULL;
|
|
Packit |
284210 |
TreeNode *parent = NULL, *i_node = NULL;
|
|
Packit |
284210 |
TreeNode *bottom_node = NULL;
|
|
Packit |
284210 |
TreePrefix *prefix = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (tree == NULL) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ConvertIPNetmask(ipdata, netmask, ip_bitmask);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix = CPTCreatePrefix(ipdata, ip_bitmask, netmask, tree->pool);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (prefix == NULL) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (tree->head == NULL) {
|
|
Packit |
284210 |
node = CPTCreateNode(tree->pool);
|
|
Packit |
284210 |
return CPTCreateHead(prefix, node, tree, netmask, ip_bitmask);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = tree->head;
|
|
Packit |
284210 |
buffer = prefix->buffer;
|
|
Packit |
284210 |
bitlen = prefix->bitlen;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (node->bit < bitlen || node->prefix == NULL) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (bitlen < node->bit) {
|
|
Packit |
284210 |
if (node->right == NULL)
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
node = node->right;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
x = SHIFT_RIGHT_MASK(node->bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (node->bit % 8));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (TREE_CHECK(buffer[x],y)) {
|
|
Packit |
284210 |
if (node->right == NULL)
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
node = node->right;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
if (node->left == NULL)
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
node = node->left;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
bottom_node = node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node->bit < bitlen)
|
|
Packit |
284210 |
bit_validation = node->bit;
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
bit_validation = bitlen;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for (i = 0; (i * NETMASK_8) < bit_validation; i++) {
|
|
Packit |
284210 |
int net = 0, div = 0;
|
|
Packit |
284210 |
int cnt = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((temp = (buffer[i] ^ bottom_node->prefix->buffer[i])) == 0) {
|
|
Packit |
284210 |
test_bit = (i + 1) * NETMASK_8;
|
|
Packit |
284210 |
continue;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
temp += temp;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
for(cnt = 0, net = NETMASK_256, div = 2; net >= NETMASK_2; net = NETMASK_256/div,
|
|
Packit |
284210 |
div += div, cnt++) {
|
|
Packit |
284210 |
if(temp >= net) {
|
|
Packit |
284210 |
test_bit = (i * NETMASK_8) + cnt;
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (bit_validation < test_bit)
|
|
Packit |
284210 |
test_bit = bit_validation;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
parent = node->parent;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (parent && test_bit <= parent->bit) {
|
|
Packit |
284210 |
node = parent;
|
|
Packit |
284210 |
parent = node->parent;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (test_bit == bitlen && node->bit == bitlen) {
|
|
Packit |
284210 |
if (node->prefix != NULL) {
|
|
Packit |
284210 |
int found = 0;
|
|
Packit |
284210 |
CPTData *prefix_data = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix_data = node->prefix->prefix_data;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(prefix_data != NULL) {
|
|
Packit |
284210 |
if (prefix_data->netmask == netmask)
|
|
Packit |
284210 |
++found;
|
|
Packit |
284210 |
prefix_data = prefix_data->next;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (found != 0) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
CPTData *prefix_data = CPTCreateCPTData(netmask, tree->pool);
|
|
Packit |
284210 |
CPTAppendToCPTDataList(prefix_data, &prefix->prefix_data);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(CheckBitmask(netmask, ip_bitmask))
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
parent = node->parent;
|
|
Packit |
284210 |
while (parent != NULL && netmask < (parent->bit + 1)) {
|
|
Packit |
284210 |
node = parent;
|
|
Packit |
284210 |
parent = parent->parent;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->count++;
|
|
Packit |
284210 |
new_node = node;
|
|
Packit |
284210 |
node->netmasks = apr_palloc(tree->pool, (node->count * sizeof(unsigned char)));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((node->count -1) == 0) {
|
|
Packit |
284210 |
node->netmasks[0] = netmask;
|
|
Packit |
284210 |
return new_node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->netmasks[node->count - 1] = netmask;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
i = node->count - 2;
|
|
Packit |
284210 |
while (i >= 0) {
|
|
Packit |
284210 |
if (netmask < node->netmasks[i]) {
|
|
Packit |
284210 |
node->netmasks[i + 1] = netmask;
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node->netmasks[i + 1] = node->netmasks[i];
|
|
Packit |
284210 |
node->netmasks[i] = netmask;
|
|
Packit |
284210 |
i--;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
node->prefix = CPTCreatePrefix(prefix->buffer, prefix->bitlen,
|
|
Packit |
284210 |
NETMASK_256-1, tree->pool);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
new_node = CPTCreateNode(tree->pool);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(new_node == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
new_node->prefix = prefix;
|
|
Packit |
284210 |
new_node->bit = prefix->bitlen;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (test_bit == bitlen) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
x = SHIFT_RIGHT_MASK(test_bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (test_bit % 8));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (TREE_CHECK(bottom_node->prefix->buffer[x],y)) {
|
|
Packit |
284210 |
new_node->right = node;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
new_node->left = node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
new_node->parent = node->parent;
|
|
Packit |
284210 |
node->parent = SetParentNode(node, new_node, tree);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
i_node = CPTCreateNode(tree->pool);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(i_node == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
//i_node->prefix = NULL;
|
|
Packit |
284210 |
i_node->bit = test_bit;
|
|
Packit |
284210 |
i_node->parent = node->parent;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node->netmasks != NULL) {
|
|
Packit |
284210 |
i = 0;
|
|
Packit |
284210 |
while(i < node->count) {
|
|
Packit |
284210 |
if (node->netmasks[i] < test_bit + 1)
|
|
Packit |
284210 |
break;
|
|
Packit |
284210 |
i++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
i_node->netmasks = apr_palloc(tree->pool, (node->count - i) * sizeof(unsigned char));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(i_node->netmasks == NULL) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
j = 0;
|
|
Packit |
284210 |
while (j < (node->count - i)) {
|
|
Packit |
284210 |
i_node->netmasks[j] = node->netmasks[i + j];
|
|
Packit |
284210 |
j++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
i_node->count = (node->count - i);
|
|
Packit |
284210 |
node->count = i;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node->count == 0) {
|
|
Packit |
284210 |
node->netmasks = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
x = SHIFT_RIGHT_MASK(test_bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (test_bit % 8));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (TREE_CHECK(buffer[x],y)) {
|
|
Packit |
284210 |
i_node->left = node;
|
|
Packit |
284210 |
i_node->right = new_node;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
i_node->left = new_node;
|
|
Packit |
284210 |
i_node->right = node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
new_node->parent = i_node;
|
|
Packit |
284210 |
node->parent = SetParentNode(node, i_node, tree);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (InsertNetmask(node, parent, new_node, tree, netmask, bitlen))
|
|
Packit |
284210 |
return new_node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return new_node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int TreeCheckData(TreePrefix *prefix, CPTData *prefix_data, unsigned int netmask) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(prefix_data != NULL) {
|
|
Packit |
284210 |
if (prefix_data->netmask == netmask) {
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
prefix_data = prefix_data->next;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
int TreePrefixNetmask(modsec_rec *msr, TreePrefix *prefix, unsigned int netmask, int flag) {
|
|
Packit |
284210 |
CPTData *prefix_data = NULL;
|
|
Packit |
284210 |
int ret = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (prefix == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "TreePrefixNetmask: prefix is NULL.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
prefix_data = prefix->prefix_data;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (flag == 1) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(prefix_data == NULL) return 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (prefix_data->netmask != netmask) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "TreePrefixNetmask: Cannot find a prefix with correct netmask.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return 0;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "TreePrefixNetmask: Found a prefix with correct netmask.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return 1;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "TreePrefixNetmask: Check if a prefix has a the correct netmask");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ret = TreeCheckData(prefix, prefix_data, netmask);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return ret;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTRetriveNode(modsec_rec *msr, unsigned char *buffer, unsigned int ip_bitmask, TreeNode *node) {
|
|
Packit |
284210 |
unsigned int x, y;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTRetriveNode: Node tree is NULL.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(buffer == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTRetriveNode: Empty ip address. Nothing to search for.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (node->bit < ip_bitmask) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
x = SHIFT_RIGHT_MASK(node->bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (node->bit % 8));
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (TREE_CHECK(buffer[x], y)) {
|
|
Packit |
284210 |
node = node->right;
|
|
Packit |
284210 |
if (node == NULL) return NULL;
|
|
Packit |
284210 |
} else {
|
|
Packit |
284210 |
node = node->left;
|
|
Packit |
284210 |
if (node == NULL) return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTRetriveNode: Found the node for provided ip address.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTRetriveParentNode(TreeNode *node) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while (node != NULL && node->netmasks == NULL)
|
|
Packit |
284210 |
node = node->parent;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTFindElementIPNetblock(modsec_rec *msr, unsigned char *ipdata, unsigned char ip_bitmask, TreeNode *node) {
|
|
Packit |
284210 |
TreeNode *netmask_node = NULL;
|
|
Packit |
284210 |
int mask = 0, bytes = 0;
|
|
Packit |
284210 |
int i = 0, j = 0;
|
|
Packit |
284210 |
int mask_bits = 0;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = CPTRetriveParentNode(node);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElementIPNetblock: Node tree is NULL.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
netmask_node = node;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while(j < netmask_node->count) {
|
|
Packit |
284210 |
bytes = ip_bitmask / 8;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
while( i < bytes ) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
mask = -1;
|
|
Packit |
284210 |
mask_bits = ((i + 1) * 8);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (mask_bits > netmask_node->netmasks[j]) {
|
|
Packit |
284210 |
if ((mask_bits - netmask_node->netmasks[j]) < 8)
|
|
Packit |
284210 |
mask = SHIFT_LEFT_MASK(mask_bits - netmask_node->netmasks[j]);
|
|
Packit |
284210 |
else
|
|
Packit |
284210 |
mask = 0;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ipdata[i] &= mask;
|
|
Packit |
284210 |
i++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = CPTRetriveNode(msr, ipdata, ip_bitmask, node);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node && node->bit != ip_bitmask) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElementIPNetblock: Found a tree node but netmask is different.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node && node->prefix == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElementIPNetblock: Found a tree node but prefix is NULL.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (memcmp(node->prefix->buffer, ipdata, bytes) == 0) {
|
|
Packit |
284210 |
mask = SHIFT_LEFT_MASK(8 - ip_bitmask % 8);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((ip_bitmask % 8) == 0) {
|
|
Packit |
284210 |
if (TreePrefixNetmask(msr, node->prefix, netmask_node->netmasks[j], FALSE)) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElementIPNetblock: Node found for provided ip address");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((node->prefix->buffer[bytes] & mask) == (ipdata[bytes] & mask)) {
|
|
Packit |
284210 |
if (TreePrefixNetmask(msr, node->prefix, netmask_node->netmasks[j], FALSE)) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElementIPNetblock: Node found for provided ip address");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
j++;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return CPTFindElementIPNetblock(msr, ipdata, ip_bitmask, netmask_node->parent);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTFindElement(modsec_rec *msr, unsigned char *ipdata, unsigned int ip_bitmask, CPTTree *tree) {
|
|
Packit |
284210 |
TreeNode *node = NULL;
|
|
Packit |
284210 |
int mask = 0, bytes = 0;
|
|
Packit |
284210 |
unsigned char temp_data[NETMASK_256-1];
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (tree == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Tree is NULL. Cannot proceed searching the ip.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (tree->head == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Tree head is NULL. Cannot proceed searching the ip.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = tree->head;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (ip_bitmask > (NETMASK_256-1)) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Netmask cannot be greater than 255");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
bytes = ip_bitmask/8;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
memset(temp_data, 0, NETMASK_256-1);
|
|
Packit |
284210 |
memcpy(temp_data, ipdata, bytes);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
node = CPTRetriveNode(msr, temp_data, ip_bitmask, node);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (node && (node->bit != ip_bitmask)) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Found a tree node but netmask is different.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Node tree is NULL.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(node->prefix == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Found a tree node but prefix is NULL.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (memcmp(node->prefix->buffer, temp_data, bytes) == 0) {
|
|
Packit |
284210 |
mask = SHIFT_LEFT_MASK(8 - ip_bitmask % 8);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((ip_bitmask % 8) == 0) {
|
|
Packit |
284210 |
if (TreePrefixNetmask(msr, node->prefix, ip_bitmask, TRUE)) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Node found for provided ip address");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if ((node->prefix->buffer[bytes] & mask) == (temp_data[bytes] & mask)) {
|
|
Packit |
284210 |
if (TreePrefixNetmask(msr, node->prefix, ip_bitmask, TRUE)) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTFindElement: Node found for provided ip address");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return node;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return CPTFindElementIPNetblock(msr, temp_data, ip_bitmask, node);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *CPTIpMatch(modsec_rec *msr, unsigned char *ipdata, CPTTree *tree, int type) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(tree == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTIpMatch: Tree is NULL. Cannot proceed searching the ip.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(ipdata == NULL) {
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTIpMatch: Empty ip address. Nothing to search for.");
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
switch(type) {
|
|
Packit |
284210 |
case IPV4_TREE:
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTIpMatch: Searching ip type 0x%x", type);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return CPTFindElement(msr, ipdata, NETMASK_32, tree);
|
|
Packit |
284210 |
case IPV6_TREE:
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTIpMatch: Searching ip type 0x%x", type);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return CPTFindElement(msr, ipdata, NETMASK_128, tree);
|
|
Packit |
284210 |
default:
|
|
Packit |
284210 |
if (msr && msr->txcfg->debuglog_level >= 9) {
|
|
Packit |
284210 |
msr_log(msr, 9, "CPTIpMatch: Unknown ip type 0x%x", type);
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
TreeNode *TreeAddIP(const char *buffer, CPTTree *tree, int type) {
|
|
Packit |
284210 |
unsigned long ip, ret;
|
|
Packit |
284210 |
unsigned char netmask_v4 = NETMASK_32, netmask_v6 = NETMASK_128;
|
|
Packit |
284210 |
char ip_strv4[NETMASK_32], ip_strv6[NETMASK_128];
|
|
Packit |
284210 |
struct in_addr addr4;
|
|
Packit |
284210 |
struct in6_addr addr6;
|
|
Packit |
284210 |
int pos = 0;
|
|
Packit |
284210 |
char *ptr = NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(tree == NULL)
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
pos = strchr(buffer, '/') - buffer;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
switch(type) {
|
|
Packit |
284210 |
|
|
Packit |
284210 |
case IPV4_TREE:
|
|
Packit |
284210 |
memset(&addr4, 0, sizeof(addr4));
|
|
Packit |
284210 |
memset(ip_strv4, 0x0, NETMASK_32);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
strncpy(ip_strv4, buffer, sizeof(ip_strv4));
|
|
Packit |
284210 |
*(ip_strv4 + (sizeof(ip_strv4) - 1)) = '\0';
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ptr = strdup(ip_strv4);
|
|
Packit |
284210 |
netmask_v4 = is_netmask_v4(ptr);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (netmask_v4 > NETMASK_32) {
|
|
Packit |
284210 |
free(ptr);
|
|
Packit |
284210 |
ptr = NULL;
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(ptr != NULL) {
|
|
Packit |
284210 |
free(ptr);
|
|
Packit |
284210 |
ptr = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(netmask_v4 == 0) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (netmask_v4 != NETMASK_32 && pos < strlen(ip_strv4)) {
|
|
Packit |
284210 |
ip_strv4[pos] = '\0';
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ret = inet_pton(AF_INET, ip_strv4, &addr4);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (ret <= 0) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ip = addr4.s_addr;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
tree->count++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return CPTAddElement((unsigned char *)&ip, NETMASK_32, tree, netmask_v4);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
case IPV6_TREE:
|
|
Packit |
284210 |
memset(&addr6, 0, sizeof(addr6));
|
|
Packit |
284210 |
memset(ip_strv6, 0x0, NETMASK_128);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
strncpy(ip_strv6, buffer, sizeof(ip_strv6));
|
|
Packit |
284210 |
*(ip_strv6 + sizeof(ip_strv6) - 1) = '\0';
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ptr = strdup(ip_strv6);
|
|
Packit |
284210 |
netmask_v6 = is_netmask_v6(ptr);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (netmask_v6 > NETMASK_128) {
|
|
Packit |
284210 |
free(ptr);
|
|
Packit |
284210 |
ptr = NULL;
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(ptr != NULL) {
|
|
Packit |
284210 |
free(ptr);
|
|
Packit |
284210 |
ptr = NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if(netmask_v6 == 0) {
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
else if (netmask_v6 != NETMASK_128 && pos < strlen(ip_strv6)) {
|
|
Packit |
284210 |
ip_strv6[pos] = '\0';
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
ret = inet_pton(AF_INET6, ip_strv6, &addr6);
|
|
Packit |
284210 |
|
|
Packit |
284210 |
if (ret <= 0)
|
|
Packit |
284210 |
{
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
tree->count++;
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return CPTAddElement((unsigned char *)&addr6.s6_addr, NETMASK_128, tree, netmask_v6);
|
|
Packit |
284210 |
default:
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|
|
Packit |
284210 |
|
|
Packit |
284210 |
return NULL;
|
|
Packit |
284210 |
}
|