Net-Patricia
view release on metacpan or search on metacpan
libpatricia/patricia.c view on Meta::CPAN
/* ascii2prefix
*/
prefix_t *
ascii2prefix (int family, char *string)
{
u_long bitlen, maxbitlen = 0;
char *cp;
struct in_addr sin;
#ifdef HAVE_IPV6
struct in6_addr sin6;
#endif /* HAVE_IPV6 */
int result;
char save[MAXLINE];
if (string == NULL)
return (NULL);
/* easy way to handle both families */
if (family == 0) {
family = AF_INET;
#ifdef HAVE_IPV6
if (strchr (string, ':')) family = AF_INET6;
#endif /* HAVE_IPV6 */
}
if (family == AF_INET) {
maxbitlen = sizeof(struct in_addr) * 8;
}
#ifdef HAVE_IPV6
else if (family == AF_INET6) {
maxbitlen = sizeof(struct in6_addr) * 8;
}
#endif /* HAVE_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 ((result = my_inet_pton (AF_INET, string, &sin)) <= 0)
return (NULL);
return (New_Prefix (AF_INET, &sin, bitlen));
}
#ifdef HAVE_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 (New_Prefix (AF_INET6, &sin6, bitlen));
#else
if ((result = inet_pton (AF_INET6, string, &sin6)) <= 0)
return (NULL);
#endif /* NT */
return (New_Prefix (AF_INET6, &sin6, bitlen));
}
#endif /* HAVE_IPV6 */
else
return (NULL);
}
prefix_t *
Ref_Prefix (prefix_t * prefix)
{
if (prefix == NULL)
return (NULL);
if (prefix->ref_count == 0) {
/* make a copy in case of a static prefix */
return (New_Prefix2 (prefix->family, &prefix->add, prefix->bitlen, NULL));
}
prefix->ref_count++;
/* fprintf(stderr, "[A %s, %d]\n", prefix_toa (prefix), prefix->ref_count); */
return (prefix);
}
void
Deref_Prefix (prefix_t * prefix)
{
if (prefix == NULL)
return;
/* for secure programming, raise an assert. no static prefix can call this */
assert (prefix->ref_count > 0);
prefix->ref_count--;
assert (prefix->ref_count >= 0);
if (prefix->ref_count <= 0) {
Delete (prefix);
return;
}
}
/* } */
/* #define PATRICIA_DEBUG 1 */
static int num_active_patricia = 0;
/* these routines support continuous mask only */
patricia_tree_t *
New_Patricia (int maxbits)
{
patricia_tree_t *patricia = calloc(1, sizeof *patricia);
patricia->maxbits = maxbits;
patricia->head = NULL;
patricia->num_active_node = 0;
assert (maxbits <= PATRICIA_MAXBITS); /* XXX */
num_active_patricia++;
( run in 2.417 seconds using v1.01-cache-2.11-cpan-97f6503c9c8 )