Various fixes to patricia tree handling

This commit is contained in:
Luca Deri 2020-05-06 11:13:57 +02:00
parent 48282369e2
commit 7855e0318d
3 changed files with 160 additions and 149 deletions

View file

@ -1694,16 +1694,14 @@ static int ac_match_handler(AC_MATCH_t *m, AC_TEXT_t *txt, AC_REP_t *match) {
/* ******************************************************************** */
static int fill_prefix_v4(prefix_t *p, const struct in_addr *a, int b, int mb) {
do {
if(b < 0 || b > mb)
return(-1);
if(b < 0 || b > mb)
return(-1);
memset(p, 0, sizeof(prefix_t));
memcpy(&p->add.sin, a, (mb + 7) / 8);
p->family = AF_INET;
p->bitlen = b;
p->ref_count = 0;
} while (0);
memset(p, 0, sizeof(prefix_t));
memcpy(&p->add.sin, a, (mb + 7) / 8);
p->family = AF_INET;
p->bitlen = b;
p->ref_count = 0;
return(0);
}
@ -1770,6 +1768,7 @@ static patricia_node_t *add_to_ptree(patricia_tree_t *tree, int family, void *ad
fill_prefix_v4(&prefix, (struct in_addr *) addr, bits, tree->maxbits);
node = ndpi_patricia_lookup(tree, &prefix);
if(node) memset(&node->value, 0, sizeof(node->value));
return(node);
}
@ -1858,7 +1857,7 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp
char *ptr = strrchr(value, '/');
u_int16_t port = 0; /* Format ip:8.248.73.247:443 */
char *double_column;
if(ptr) {
ptr[0] = '\0';
ptr++;
@ -1867,7 +1866,7 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp
double_column[0] = '\0';
port = atoi(&double_column[1]);
}
if(atoi(ptr) >= 0 && atoi(ptr) <= 32)
bits = atoi(ptr);
} else {
@ -1877,16 +1876,18 @@ static int ndpi_add_host_ip_subprotocol(struct ndpi_detection_module_struct *ndp
*/
double_column = strrchr(value, ':');
if(double_column)
port = atoi(&double_column[1]);
if(double_column) {
double_column[0] = '\0';
port = atoi(&double_column[1]);
}
}
inet_pton(AF_INET, value, &pin);
if((node = add_to_ptree(ndpi_str->protocols_ptree, AF_INET, &pin, bits)) != NULL) {
node->value.user_value = protocol_id; // node->value.additional_user_value = port;
}
return(0);
}
@ -2231,7 +2232,7 @@ int ndpi_match_string(void *_automa, char *string_to_match) {
int ndpi_match_string_id(void *_automa, char *string_to_match, u_int match_len, u_int16_t *id) {
AC_TEXT_t ac_input_text;
AC_AUTOMATA_t *automa = (AC_AUTOMATA_t *) _automa;
AC_REP_t match = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED};
AC_REP_t match = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED };
int rc;
*id = -1;
@ -2333,7 +2334,7 @@ int ndpi_get_custom_category_match(struct ndpi_detection_module_struct *ndpi_str
if(node) {
*id = node->value.user_value;
return(0);
}
@ -4247,10 +4248,10 @@ int ndpi_load_ip_category(struct ndpi_detection_module_struct *ndpi_str, const c
if((node = add_to_ptree(ndpi_str->custom_categories.ipAddresses_shadow, AF_INET, &pin, bits)) != NULL) {
node->value.user_value = (u_int16_t)category; // node->value.additional_user_value = 0;
}
return(0);
}
/* ********************************************************************************* */
@ -4451,7 +4452,7 @@ int ndpi_fill_ip_protocol_category(struct ndpi_detection_module_struct *ndpi_str
if(node) {
ret->category = (ndpi_protocol_category_t) node->value.user_value;
return(1);
}
}
@ -4487,7 +4488,7 @@ void ndpi_fill_protocol_category(struct ndpi_detection_module_struct *ndpi_str,
u_int16_t id;
int rc = ndpi_match_custom_category(ndpi_str, (char *) flow->protos.stun_ssl.ssl.client_requested_server_name,
strlen(flow->protos.stun_ssl.ssl.client_requested_server_name), &id);
if(rc == 0) {
flow->category = ret->category = (ndpi_protocol_category_t) id;
return;
@ -6255,7 +6256,7 @@ int gettimeofday(struct timeval *tp, struct timezone *tzp) {
}
#endif
int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
int NDPI_BITMASK_COMPARE(NDPI_PROTOCOL_BITMASK a, NDPI_PROTOCOL_BITMASK b) {
int i;
for (i = 0; i < NDPI_NUM_FDS_BITS; i++) {
@ -6279,7 +6280,7 @@ int NDPI_BITMASK_IS_EMPTY(NDPI_PROTOCOL_BITMASK a) {
void NDPI_DUMP_BITMASK(NDPI_PROTOCOL_BITMASK a) {
int i;
for (i = 0; i < NDPI_NUM_FDS_BITS; i++)
printf("[%d=%u]", i, a.fds_bits[i]);
@ -6513,7 +6514,7 @@ int ndpi_ptree_insert(ndpi_ptree_t *tree, const ndpi_ip_addr_t *addr,
if(node != NULL) {
node->value.user_value = user_data; // node->value.additional_user_value = 0;
return(0);
}
@ -6539,7 +6540,7 @@ int ndpi_ptree_match_addr(ndpi_ptree_t *tree,
if(node) {
*user_data = node->value.user_value;
return(0);
}

View file

@ -79,15 +79,15 @@
/* { from mrt.h */
typedef struct the_prefix4_t {
unsigned short family; /* AF_INET | AF_INET6 */
unsigned short bitlen; /* same as mask? */
u_int16_t family; /* AF_INET | AF_INET6 */
u_int16_t bitlen; /* same as mask? */
int ref_count; /* reference count */
struct in_addr sin;
} prefix4_t;
typedef struct the_prefix_t {
unsigned short family; /* AF_INET | AF_INET6 */
unsigned short bitlen; /* same as mask? */
u_int16_t family; /* AF_INET | AF_INET6 */
u_int16_t bitlen; /* same as mask? */
int ref_count; /* reference count */
union {
struct in_addr sin;
@ -108,7 +108,7 @@ union patricia_node_value_t {
};
typedef struct _patricia_node_t {
u_int bit; /* flag if this node used */
u_int16_t bit; /* flag if this node used */
prefix_t *prefix; /* who we are in patricia tree */
struct _patricia_node_t *l, *r; /* left and right children */
struct _patricia_node_t *parent;/* may be used */
@ -118,7 +118,7 @@ typedef struct _patricia_node_t {
typedef struct _patricia_tree_t {
patricia_node_t *head;
u_int maxbits; /* for IP, 32 bit addresses */
u_int16_t maxbits; /* for IP, 32 bit addresses */
int num_active_node; /* for debug purpose */
} patricia_tree_t;
@ -132,7 +132,7 @@ patricia_node_t * ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_
int inclusive);
patricia_node_t *ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix);
void ndpi_patricia_remove (patricia_tree_t *patricia, patricia_node_t *node);
patricia_tree_t *ndpi_New_Patricia (int maxbits);
patricia_tree_t *ndpi_New_Patricia (u_int16_t maxbits);
void ndpi_Clear_Patricia (patricia_tree_t *patricia, void_fn_t func);
void ndpi_Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func);
void ndpi_patricia_process (patricia_tree_t *patricia, void_fn2_t func);

View file

@ -56,7 +56,7 @@
#include "ndpi_patricia.h"
#include "ndpi_api.h"
void ndpi_DeleteEntry(void *a) {
static void ndpi_DeleteEntry(void *a) {
ndpi_free(a);
}
@ -65,8 +65,7 @@ void ndpi_DeleteEntry(void *a) {
/* ndpi_prefix_tochar
* convert prefix information to bytes
*/
u_char *
ndpi_prefix_tochar (prefix_t * prefix)
static u_char* ndpi_prefix_tochar (prefix_t * prefix)
{
if(prefix == NULL)
return (NULL);
@ -74,20 +73,20 @@ ndpi_prefix_tochar (prefix_t * prefix)
return ((u_char *) & prefix->add.sin);
}
int ndpi_comp_with_mask (void *addr, void *dest, u_int mask) {
static int ndpi_comp_with_mask (void *addr, void *dest, u_int mask) {
uint32_t *pa = addr;
uint32_t *pd = dest;
uint32_t m;
for(;mask >= 32; mask -= 32, pa++,pd++)
if(*pa != *pd) return 0;
if(*pa != *pd) return 0;
if(!mask) return 1;
m = htonl((~0u) << (32-mask));
return (*pa & m) == (*pd &m);
}
#if 0
/* this allows incomplete prefix */
int
ndpi_my_inet_pton (int af, const char *src, void *dst)
static int ndpi_my_inet_pton (int af, const char *src, void *dst)
{
if(af == AF_INET) {
int i;
@ -106,7 +105,7 @@ ndpi_my_inet_pton (int af, const char *src, void *dst)
return (0);
c = *src++;
} while (c && isdigit (c));
xp[i] = val;
xp[i] = (u_char)val;
if(c == '\0')
break;
if(c != '.')
@ -118,24 +117,25 @@ ndpi_my_inet_pton (int af, const char *src, void *dst)
return (1);
#if defined(PATRICIA_IPV6)
} else if(af == AF_INET6) {
return (inet_pton (af, src, dst));
return (inet_pton (af, src, dst));
#endif /* PATRICIA_IPV6 */
} else {
} else {
#ifndef NT
errno = EAFNOSUPPORT;
errno = EAFNOSUPPORT;
#endif /* NT */
return -1;
}
}
#endif
#define PATRICIA_MAX_THREADS 16
#if 0
/*
* convert prefix information to ascii string with length
* thread safe and (almost) re-entrant implementation
*/
char *
ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
static char * ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
{
if(prefix == NULL)
return ((char*)"(Null)");
@ -193,22 +193,20 @@ ndpi_prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
/* ndpi_prefix_toa2
* convert prefix information to ascii string
*/
char *
ndpi_prefix_toa2 (prefix_t *prefix, char *buff)
static char * ndpi_prefix_toa2 (prefix_t *prefix, char *buff)
{
return (ndpi_prefix_toa2x (prefix, buff, 0));
}
/* ndpi_prefix_toa
*/
char *
ndpi_prefix_toa (prefix_t * prefix)
static char * ndpi_prefix_toa (prefix_t * prefix)
{
return (ndpi_prefix_toa2 (prefix, (char *) NULL));
}
#endif
prefix_t *
ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
static prefix_t * ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
{
int dynamic_allocated = 0;
int default_bitlen = sizeof(struct in_addr) * 8;
@ -242,8 +240,8 @@ ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
return (NULL);
}
prefix->bitlen = (bitlen >= 0)? bitlen: default_bitlen;
prefix->family = family;
prefix->bitlen = (u_int16_t)((bitlen >= 0) ? bitlen : default_bitlen);
prefix->family = (u_int16_t)family;
prefix->ref_count = 0;
if(dynamic_allocated) {
prefix->ref_count++;
@ -252,83 +250,14 @@ ndpi_New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
return (prefix);
}
prefix_t *
ndpi_New_Prefix (int family, void *dest, int bitlen)
#if 0
static prefix_t * ndpi_New_Prefix (int family, void *dest, int bitlen)
{
return (ndpi_New_Prefix2 (family, dest, bitlen, NULL));
}
#endif
/* ndpi_ascii2prefix */
prefix_t *
ndpi_ascii2prefix (int family, char *string)
{
long bitlen;
long maxbitlen = 0;
char *cp;
struct in_addr sin;
#if defined(PATRICIA_IPV6)
struct in6_addr sin6;
#endif /* PATRICIA_IPV6 */
char save[MAXLINE];
if(string == NULL)
return (NULL);
/* easy way to handle both families */
if(family == 0) {
family = AF_INET;
#if defined(PATRICIA_IPV6)
if(strchr (string, ':')) family = AF_INET6;
#endif /* PATRICIA_IPV6 */
}
if(family == AF_INET) {
maxbitlen = sizeof(struct in_addr) * 8;
}
#if defined(PATRICIA_IPV6)
else if(family == AF_INET6) {
maxbitlen = sizeof(struct in6_addr) * 8;
}
#endif /* PATRICIA_IPV6 */
if((cp = strchr (string, '/')) != NULL) {
bitlen = atol (cp + 1);
/* *cp = '\0'; */
/* copy the string to save. Avoid destroying the string */
assert (cp - string < MAXLINE);
memcpy (save, string, cp - string);
save[cp - string] = '\0';
string = save;
if((bitlen < 0) || (bitlen > maxbitlen))
bitlen = maxbitlen;
} else {
bitlen = maxbitlen;
}
if(family == AF_INET) {
if(ndpi_my_inet_pton (AF_INET, string, &sin) <= 0)
return (NULL);
return (ndpi_New_Prefix (AF_INET, &sin, bitlen));
}
#if defined(PATRICIA_IPV6)
else if(family == AF_INET6) {
// Get rid of this with next IPv6 upgrade
#if defined(NT) && !defined(HAVE_INET_NTOP)
inet6_addr(string, &sin6);
return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
#else
if(inet_pton (AF_INET6, string, &sin6) <= 0)
return (NULL);
#endif /* NT */
return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
}
#endif /* PATRICIA_IPV6 */
else
return (NULL);
}
prefix_t *
static prefix_t *
ndpi_Ref_Prefix (prefix_t * prefix)
{
if(prefix == NULL)
@ -342,7 +271,7 @@ ndpi_Ref_Prefix (prefix_t * prefix)
return (prefix);
}
void
static void
ndpi_Deref_Prefix (prefix_t * prefix)
{
if(prefix == NULL)
@ -358,21 +287,21 @@ ndpi_Deref_Prefix (prefix_t * prefix)
}
}
/* #define PATRICIA_DEBUG 1 */
// #define PATRICIA_DEBUG 1
static int num_active_patricia = 0;
/* these routines support continuous mask only */
patricia_tree_t *
ndpi_New_Patricia (int maxbits)
ndpi_New_Patricia (u_int16_t maxbits)
{
patricia_tree_t *patricia = (patricia_tree_t*)ndpi_calloc(1, sizeof *patricia);
patricia->maxbits = maxbits;
patricia->head = NULL;
patricia->num_active_node = 0;
assert((u_int)maxbits <= PATRICIA_MAXBITS); /* XXX */
assert((u_int16_t)maxbits <= PATRICIA_MAXBITS); /* XXX */
num_active_patricia++;
return (patricia);
}
@ -477,7 +406,7 @@ ndpi_patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix)
{
patricia_node_t *node;
u_char *addr;
u_int bitlen;
u_int16_t bitlen;
assert (patricia);
assert (prefix);
@ -521,17 +450,19 @@ ndpi_patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix)
#ifdef PATRICIA_DEBUG
if(node->prefix)
fprintf (stderr, "patricia_search_exact: stop at %s/%d\n",
ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
fprintf (stderr, "patricia_search_exact: stop at %s/%d [node->bit: %u][bitlen: %u]\n",
ndpi_prefix_toa (node->prefix), node->prefix->bitlen, node->bit, bitlen);
else
fprintf (stderr, "patricia_search_exact: stop at %u\n", node->bit);
#endif /* PATRICIA_DEBUG */
if(node->bit > bitlen || node->prefix == NULL)
return (NULL);
assert (node->bit == bitlen);
assert (node->bit == node->prefix->bitlen);
if(ndpi_comp_with_mask (ndpi_prefix_tochar (node->prefix), ndpi_prefix_tochar (prefix),
bitlen)) {
bitlen)) {
#ifdef PATRICIA_DEBUG
fprintf (stderr, "patricia_search_exact: found %s/%d\n",
ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
@ -549,7 +480,7 @@ ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inc
patricia_node_t *node;
patricia_node_t *stack[PATRICIA_MAXBITS + 1];
u_char *addr;
u_int bitlen;
u_int16_t bitlen;
int cnt = 0;
assert (patricia);
@ -564,7 +495,6 @@ ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inc
bitlen = prefix->bitlen;
while (node->bit < bitlen) {
if(node->prefix) {
#ifdef PATRICIA_DEBUG
fprintf (stderr, "patricia_search_best: push %s/%d\n",
@ -600,9 +530,15 @@ ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inc
break;
}
if(inclusive && node && node->prefix)
if(inclusive && node && node->prefix) {
#ifdef PATRICIA_DEBUG
fprintf (stderr, "patricia_search_best: found node %s/%d [searching %s/%d]\n",
ndpi_prefix_toa (node->prefix), node->prefix->bitlen,
ndpi_prefix_toa (prefix), prefix->bitlen);
#endif
stack[cnt++] = node;
}
#ifdef PATRICIA_DEBUG
if(node == NULL)
fprintf (stderr, "patricia_search_best: stop at null\n");
@ -623,8 +559,8 @@ ndpi_patricia_search_best2 (patricia_tree_t *patricia, prefix_t *prefix, int inc
ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
#endif /* PATRICIA_DEBUG */
if(ndpi_comp_with_mask (ndpi_prefix_tochar (node->prefix),
ndpi_prefix_tochar (prefix),
node->prefix->bitlen) && node->prefix->bitlen <= bitlen) {
ndpi_prefix_tochar (prefix),
node->prefix->bitlen) && node->prefix->bitlen <= bitlen) {
#ifdef PATRICIA_DEBUG
fprintf (stderr, "patricia_search_best: found %s/%d\n",
ndpi_prefix_toa (node->prefix), node->prefix->bitlen);
@ -648,10 +584,15 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
{
patricia_node_t *node, *new_node, *parent, *glue;
u_char *addr, *test_addr;
u_int bitlen, check_bit, differ_bit;
u_int16_t bitlen, check_bit, differ_bit;
int i, j;
assert (patricia);
#ifdef PATRICIA_DEBUG
fprintf (stderr, "patricia_lookup() %s/%d (head)\n",
ndpi_prefix_toa (prefix), prefix->bitlen);
#endif /* PATRICIA_DEBUG */
assert (patricia);
assert (prefix);
assert (prefix->bitlen <= patricia->maxbits);
@ -676,9 +617,8 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
node = patricia->head;
while (node->bit < bitlen || node->prefix == NULL) {
if(node->bit < patricia->maxbits &&
BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
if(node->r == NULL)
break;
#ifdef PATRICIA_DEBUG
@ -733,6 +673,7 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
differ_bit = i * 8 + j;
break;
}
if(differ_bit > check_bit)
differ_bit = check_bit;
#ifdef PATRICIA_DEBUG
@ -781,7 +722,7 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
if(node->bit == differ_bit) {
new_node->parent = node;
if(node->bit < patricia->maxbits &&
BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
assert (node->r == NULL);
node->r = new_node;
}
@ -798,7 +739,7 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
if(bitlen == differ_bit) {
if(bitlen < patricia->maxbits &&
BIT_TEST (test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) {
BIT_TEST (test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) {
new_node->r = node;
}
else {
@ -831,7 +772,7 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
glue->data = NULL;
patricia->num_active_node++;
if(differ_bit < patricia->maxbits &&
BIT_TEST (addr[differ_bit >> 3], 0x80 >> (differ_bit & 0x07))) {
BIT_TEST (addr[differ_bit >> 3], 0x80 >> (differ_bit & 0x07))) {
glue->r = new_node;
glue->l = node;
}
@ -855,7 +796,7 @@ ndpi_patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix)
#ifdef PATRICIA_DEBUG
fprintf (stderr, "patricia_lookup: new_node #4 %s/%d (glue+node)\n",
ndpi_prefix_toa (prefix), prefix->bitlen);
#endif /* PATRICIA_DEBUG */
#endif /* PATRICIA_DEBUG */
}
return (new_node);
}
@ -969,6 +910,75 @@ ndpi_patricia_remove (patricia_tree_t *patricia, patricia_node_t *node)
/* { from demo.c */
#if 0
/* ndpi_ascii2prefix */
static prefix_t * ndpi_ascii2prefix (int family, char *string)
{
long bitlen;
long maxbitlen = 0;
char *cp;
struct in_addr sin;
#if defined(PATRICIA_IPV6)
struct in6_addr sin6;
#endif /* PATRICIA_IPV6 */
char save[MAXLINE];
if(string == NULL)
return (NULL);
/* easy way to handle both families */
if(family == 0) {
family = AF_INET;
#if defined(PATRICIA_IPV6)
if(strchr (string, ':')) family = AF_INET6;
#endif /* PATRICIA_IPV6 */
}
if(family == AF_INET) {
maxbitlen = sizeof(struct in_addr) * 8;
}
#if defined(PATRICIA_IPV6)
else if(family == AF_INET6) {
maxbitlen = sizeof(struct in6_addr) * 8;
}
#endif /* PATRICIA_IPV6 */
if((cp = strchr (string, '/')) != NULL) {
bitlen = atol (cp + 1);
/* *cp = '\0'; */
/* copy the string to save. Avoid destroying the string */
assert (cp - string < MAXLINE);
memcpy (save, string, cp - string);
save[cp - string] = '\0';
string = save;
if((bitlen < 0) || (bitlen > maxbitlen))
bitlen = maxbitlen;
} else {
bitlen = maxbitlen;
}
if(family == AF_INET) {
if(ndpi_my_inet_pton (AF_INET, string, &sin) <= 0)
return (NULL);
return (ndpi_New_Prefix (AF_INET, &sin, bitlen));
}
#if defined(PATRICIA_IPV6)
else if(family == AF_INET6) {
// Get rid of this with next IPv6 upgrade
#if defined(NT) && !defined(HAVE_INET_NTOP)
inet6_addr(string, &sin6);
return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
#else
if(inet_pton (AF_INET6, string, &sin6) <= 0)
return (NULL);
#endif /* NT */
return (ndpi_New_Prefix (AF_INET6, &sin6, bitlen));
}
#endif /* PATRICIA_IPV6 */
else
return (NULL);
}
patricia_node_t *
ndpi_make_and_lookup (patricia_tree_t *tree, char *string)
{