Radix Tree fixes/updates

remotes/origin/master-1.0.x
Anoop Saldanha 16 years ago committed by Victor Julien
parent 8f7cff1d53
commit eea0e2a807

@ -87,6 +87,7 @@ typedef enum {
SC_ERR_STAT_ERROR,
SC_ERR_LOGDIR_CONFIG,
SC_ERR_LOGDIR_CMDLINE,
SC_RADIX_TREE_GENERIC_ERROR,
} SCError;
const char *SCErrorToString(SCError);

@ -291,20 +291,20 @@ int SCHInfoGetHostOSFlavour(char *ip_addr_str)
return -1;
}
if ( (node = SCRadixFindKeyIPV6((uint8_t *)ipv6_addr, sc_hinfo_tree)) == NULL)
if ( (node = SCRadixFindKeyIPV6BestMatch((uint8_t *)ipv6_addr, sc_hinfo_tree)) == NULL)
return -1;
else
return *((int *)node->prefix->user);
return *((int *)node->prefix->user_data_result);
} else {
if ( (ipv4_addr = SCHInfoValidateIPV4Address(ip_addr_str)) == NULL) {
SCLogError(SC_INVALID_IPV4_ADDR, "Invalid IPV4 address");
return -1;
}
if ( (node = SCRadixFindKeyIPV4((uint8_t *)ipv4_addr, sc_hinfo_tree)) == NULL)
if ( (node = SCRadixFindKeyIPV4BestMatch((uint8_t *)ipv4_addr, sc_hinfo_tree)) == NULL)
return -1;
else
return *((int *)node->prefix->user);
return *((int *)node->prefix->user_data_result);
}
}
@ -318,11 +318,11 @@ int SCHInfoGetHostOSFlavour(char *ip_addr_str)
*/
int SCHInfoGetIPv4HostOSFlavour(uint8_t *ipv4_addr)
{
SCRadixNode *node = SCRadixFindKeyIPV4(ipv4_addr, sc_hinfo_tree);
SCRadixNode *node = SCRadixFindKeyIPV4BestMatch(ipv4_addr, sc_hinfo_tree);
if (node == NULL)
return -1;
else
return *((int *)node->prefix->user);
return *((int *)node->prefix->user_data_result);
}
/**
@ -335,11 +335,11 @@ int SCHInfoGetIPv4HostOSFlavour(uint8_t *ipv4_addr)
*/
int SCHInfoGetIPv6HostOSFlavour(uint8_t *ipv6_addr)
{
SCRadixNode *node = SCRadixFindKeyIPV6(ipv6_addr, sc_hinfo_tree);
SCRadixNode *node = SCRadixFindKeyIPV6BestMatch(ipv6_addr, sc_hinfo_tree);
if (node == NULL)
return -1;
else
return *((int *)node->prefix->user);
return *((int *)node->prefix->user_data_result);
}
void SCHInfoCleanResources(void)
@ -861,6 +861,86 @@ int SCHInfoTestValidIPV6Address08(void)
return result;
}
/**
* \test Check that valid ipv4 addresses are inserted into the host os radix
* tree, and the host os api retrieves the right value for the host os
* flavour, on supplying as arg an ipv4 addresses that has been added to
* the host os radix tree.
*/
int SCHInfoTestValidIPV4Address09(void)
{
int result = 1;
result &= (SCHInfoAddHostOSInfo("linux", "192.168.1.0", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoGetHostOSFlavour("192.168.1.0") ==
SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map));
result &= (SCHInfoAddHostOSInfo("solaris", "192.168.1.0/16", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoAddHostOSInfo("macos", "192.168.1.0/20", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoGetHostOSFlavour("192.168.1.0") ==
SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map));
result &= (SCHInfoAddHostOSInfo("vista", "192.168.50.128/25", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoGetHostOSFlavour("192.168.50.128") ==
SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map));
result &= (SCHInfoAddHostOSInfo("irix", "192.168.50.128", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoGetHostOSFlavour("192.168.50.128") ==
SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map));
result &= (SCHInfoGetHostOSFlavour("192.168.1.100") ==
SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map));
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
return 0;
SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 16);
result &= (SCHInfoGetHostOSFlavour("192.168.1.100") ==
SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map));
bzero(&servaddr, sizeof(servaddr));
if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
return 0;
SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 20);
result &= (SCHInfoGetHostOSFlavour("192.168.1.100") == -1);
result &= (SCHInfoAddHostOSInfo("solaris", "192.168.1.0/16", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoAddHostOSInfo("macos", "192.168.1.0/20", SC_HINFO_IS_IPV4) !=
-1);
result &= (SCHInfoGetHostOSFlavour("192.168.1.100") ==
SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map));
bzero(&servaddr, sizeof(servaddr));
if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
return 0;
SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 20);
result &= (SCHInfoGetHostOSFlavour("192.168.1.100") ==
SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map));
bzero(&servaddr, sizeof(servaddr));
if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
return 0;
SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 16);
result &= (SCHInfoGetHostOSFlavour("192.168.1.100") == -1);
SCHInfoCleanResources();
return result;
}
#endif /* UNITTESTS */
void SCHInfoRegisterTests(void)
@ -884,6 +964,8 @@ void SCHInfoRegisterTests(void)
SCHInfoTestValidIPV6Address07, 1);
UtRegisterTest("SCHInfoTestValidIPV6Address08",
SCHInfoTestValidIPV6Address08, 1);
UtRegisterTest("SCHInfoTestValidIPV4Address09",
SCHInfoTestValidIPV4Address09, 1);
#endif /* UNITTESTS */

File diff suppressed because it is too large Load Diff

@ -7,6 +7,18 @@
#define SC_RADIX_BITTEST(x, y) ((x) & (y))
/**
* \brief Structure that hold the user data and the netmask associated with it.
*/
typedef struct SCRadixUserData_ {
/* holds the netmask value that corresponds to this user data pointer */
uint8_t netmask;
/* holds a pointer to the user data associated with the particular netmask */
void *user;
/* pointer to the next user data in the list */
struct SCRadixUserData_ *next;
} SCRadixUserData;
/**
* \brief Structure for the prefix/key in the radix tree
*/
@ -17,12 +29,16 @@ typedef struct SCRadixPrefix_ {
/* the key that has been stored in the tree */
uint8_t *stream;
/* if this is a prefix that holds a netblock, this field holds the
* netmask, 255 otherwise */
uint8_t netmask;
/* any user data that has to be associated with this key. We need a user
* data field for each netblock value possible since one ip can be associated
* with any of the the 32 or 128 netblocks. Also for non-ips, we store the
* netmask as 255 in SCRadixUserData->netmask */
SCRadixUserData *user_data;
/* any user data that has to be associated with this key */
void *user;
/* Used to hold the user data from radix tree search. More of a convenience
* that lets anyone using the API, directly get a reference to the user
* data which is associated with the search results */
void *user_data_result;
} SCRadixPrefix;
/**
@ -61,6 +77,9 @@ typedef struct SCRadixTree_ {
} SCRadixTree;
struct in_addr *SCRadixValidateIPV4Address(const char *);
struct in6_addr *SCRadixValidateIPV6Address(const char *);
SCRadixTree *SCRadixCreateRadixTree(void (*Free)(void*));
void SCRadixReleaseRadixTree(SCRadixTree *);
@ -73,12 +92,16 @@ SCRadixNode *SCRadixAddKeyIPV6Netblock(uint8_t *, SCRadixTree *, void *,
uint8_t);
void SCRadixRemoveKeyGeneric(uint8_t *, uint16_t, SCRadixTree *);
void SCRadixRemoveKeyIPV4Netblock(uint8_t *, SCRadixTree *, uint8_t);
void SCRadixRemoveKeyIPV4(uint8_t *, SCRadixTree *);
void SCRadixRemoveKeyIPV6Netblock(uint8_t *, SCRadixTree *, uint8_t);
void SCRadixRemoveKeyIPV6(uint8_t *, SCRadixTree *);
SCRadixNode *SCRadixFindKeyGeneric(uint8_t *, uint16_t, SCRadixTree *);
SCRadixNode *SCRadixFindKeyIPV4(uint8_t *, SCRadixTree *);
SCRadixNode *SCRadixFindKeyIPV6(uint8_t *, SCRadixTree *);
SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *, SCRadixTree *);
SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *, SCRadixTree *);
SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *, SCRadixTree *);
SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *, SCRadixTree *);
void SCRadixPrintTree(SCRadixTree *);

Loading…
Cancel
Save