Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
prnetdb.c File Reference
#include "primpl.h"
#include <string.h>

Go to the source code of this file.

Classes

struct  PRAddrInfoFB

Defines

#define _MD_GETHOST_ERRNO()   _MD_ERRNO()
#define LOCK_DNS()   PR_Lock(_pr_dnsLock)
#define UNLOCK_DNS()   PR_Unlock(_pr_dnsLock)
#define _PR_IN6_IS_ADDR_UNSPECIFIED(a)
#define _PR_IN6_IS_ADDR_LOOPBACK(a)
#define _PR_IN6_IS_ADDR_V4MAPPED(a)
#define _PR_IN6_IS_ADDR_V4COMPAT(a)
#define _PR_IN6_V4MAPPED_TO_IPADDR(a)   ((a)->pr_s6_addr32[3])
#define GETHOSTBYNAME(name)   gethostbyname(name)
#define GETHOSTBYNAME2(name, af)   gethostbyname2(name, af)
#define GETHOSTBYADDR(addr, addrlen, af)   gethostbyaddr(addr, addrlen, af)
#define XX   127
#define STUFF(c)

Typedefs

typedef enum _PRIPAddrConversion _PRIPAddrConversion
typedef struct PRAddrInfoFB PRAddrInfoFB

Enumerations

enum  _PRIPAddrConversion { _PRIPAddrNoConversion, _PRIPAddrIPv4Mapped, _PRIPAddrIPv4Compat }

Functions

void _PR_InitNet (void)
void _PR_CleanupNet (void)
static char * Alloc (PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align)
static void MakeIPv4MappedAddr (const char *v4, char *v6)
static void MakeIPv4CompatAddr (const char *v4, char *v6)
static PRStatus CopyHostent (struct hostent *from, char **buf, PRIntn *bufsize, _PRIPAddrConversion conversion, PRHostEnt *to)
static PRStatus CopyProtoent (struct protoent *from, char *buf, PRIntn bufsize, PRProtoEnt *to)
 PR_IMPLEMENT (PRStatus)
static struct protoentgetprotobyname_r (const char *name)
static struct protoentgetprotobynumber_r (PRInt32 number)
PRUintn _PR_NetAddrSize (const PRNetAddr *addr)
 PR_IMPLEMENT (PRIntn)
 PR_IsNetAddrType (const PRNetAddr *addr, PRNetAddrValue val)
static int StringToV6Addr (const char *string, PRIPv6Addr *addr)
static const char * V6AddrToString (const PRIPv6Addr *addr, char *buf, PRUint32 size)
 PR_IMPLEMENT (void)
 PR_IMPLEMENT (PRUint16)
 PR_IMPLEMENT (PRUint32)
 PR_IMPLEMENT (PRUint64)
static PRAddrInfopr_GetAddrInfoByNameFB (const char *hostname, PRUint16 af, PRIntn flags)
 PR_IMPLEMENT (PRAddrInfo *)
 PR_IMPLEMENT (void *)
 PR_IMPLEMENT (const char *)

Variables

PRLock_pr_dnsLock = NULL
PRLock_getproto_lock = NULL
const PRIPv6Addr _pr_in6addr_any
const PRIPv6Addr _pr_in6addr_loopback
static const unsigned char index_hex [256]
static const char * basis_hex = "0123456789abcdef"

Class Documentation

struct PRAddrInfoFB

Definition at line 2045 of file prnetdb.c.

Collaboration diagram for PRAddrInfoFB:
Class Members
char buf
PRBool has_cname
PRHostEnt hostent

Define Documentation

Definition at line 53 of file prnetdb.c.

Value:
(((a)->pr_s6_addr32[0] == 0)       &&     \
               ((a)->pr_s6_addr32[1] == 0)              &&     \
               ((a)->pr_s6_addr32[2] == 0)              &&     \
               ((a)->pr_s6_addr[12] == 0)        &&     \
               ((a)->pr_s6_addr[13] == 0)        &&     \
               ((a)->pr_s6_addr[14] == 0)        &&     \
               ((a)->pr_s6_addr[15] == 0x1U))

Definition at line 135 of file prnetdb.c.

Value:
(((a)->pr_s6_addr32[0] == 0) &&    \
                            ((a)->pr_s6_addr32[1] == 0) &&            \
                            ((a)->pr_s6_addr32[2] == 0) &&            \
                            ((a)->pr_s6_addr32[3] == 0))

Definition at line 129 of file prnetdb.c.

Value:
(((a)->pr_s6_addr32[0] == 0) &&    \
              ((a)->pr_s6_addr32[1] == 0) &&            \
              ((a)->pr_s6_addr32[2] == 0))

Definition at line 167 of file prnetdb.c.

Value:
(((a)->pr_s6_addr32[0] == 0)       &&     \
              ((a)->pr_s6_addr32[1] == 0) &&     \
              ((a)->pr_s6_addr[8] == 0)          &&     \
              ((a)->pr_s6_addr[9] == 0)          &&     \
              ((a)->pr_s6_addr[10] == 0xff)      &&     \
              ((a)->pr_s6_addr[11] == 0xff))

Definition at line 159 of file prnetdb.c.

Definition at line 172 of file prnetdb.c.

Definition at line 668 of file prnetdb.c.

Definition at line 666 of file prnetdb.c.

#define GETHOSTBYNAME2 (   name,
  af 
)    gethostbyname2(name, af)

Definition at line 667 of file prnetdb.c.

Definition at line 79 of file prnetdb.c.

#define STUFF (   c)
Value:
do { \
    if (!size--) return NULL; \
    *buf++ = (c); \
} while (0)

Definition at line 80 of file prnetdb.c.

#define XX   127

Definition at line 1534 of file prnetdb.c.


Typedef Documentation

typedef struct PRAddrInfoFB PRAddrInfoFB

Enumeration Type Documentation

Enumerator:
_PRIPAddrNoConversion 
_PRIPAddrIPv4Mapped 
_PRIPAddrIPv4Compat 

Definition at line 487 of file prnetdb.c.


Function Documentation

Definition at line 440 of file prnetdb.c.

{
#if !defined(_PR_NO_DNS_LOCK)
    if (_pr_dnsLock) {
        PR_DestroyLock(_pr_dnsLock);
        _pr_dnsLock = NULL;
    }
#endif
#if !defined(_PR_HAVE_GETPROTO_R)
    if (_getproto_lock) {
        PR_DestroyLock(_getproto_lock);
        _getproto_lock = NULL;
    }
#endif
#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
    if (_pr_query_ifs_lock) {
        PR_DestroyLock(_pr_query_ifs_lock);
        _pr_query_ifs_lock = NULL;
    }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 418 of file prnetdb.c.

{
#if defined(XP_UNIX)
#ifdef HAVE_NETCONFIG
       /*
        * This one-liner prevents the endless re-open's and re-read's of
        * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc.
        */
        (void)setnetconfig();
#endif
#endif
#if !defined(_PR_NO_DNS_LOCK)
       _pr_dnsLock = PR_NewLock();
#endif
#if !defined(_PR_HAVE_GETPROTO_R)
       _getproto_lock = PR_NewLock();
#endif
#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
       _pr_query_ifs_lock = PR_NewLock();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUintn _PR_NetAddrSize ( const PRNetAddr addr)

Definition at line 1364 of file prnetdb.c.

{
    PRUintn addrsize;

    /*
     * RFC 2553 added a new field (sin6_scope_id) to
     * struct sockaddr_in6.  PRNetAddr's ipv6 member has a
     * scope_id field to match the new field.  In order to
     * work with older implementations supporting RFC 2133,
     * we take the size of struct sockaddr_in6 instead of
     * addr->ipv6.
     */
    if (AF_INET == addr->raw.family)
        addrsize = sizeof(addr->inet);
    else if (PR_AF_INET6 == addr->raw.family)
#if defined(_PR_INET6)
        addrsize = sizeof(struct sockaddr_in6);
#else
        addrsize = sizeof(addr->ipv6);
#endif
#if defined(XP_UNIX) || defined(XP_OS2_EMX)
    else if (AF_UNIX == addr->raw.family)
        addrsize = sizeof(addr->local);
#endif
    else addrsize = 0;

    return addrsize;
}  /* _PR_NetAddrSize */
static char* Alloc ( PRIntn  amount,
char **  bufp,
PRIntn *  buflenp,
PRIntn  align 
) [static]

Definition at line 466 of file prnetdb.c.

{
       char *buf = *bufp;
       PRIntn buflen = *buflenp;

       if (align && ((long)buf & (align - 1))) {
              PRIntn skip = align - ((ptrdiff_t)buf & (align - 1));
              if (buflen < skip) {
                     return 0;
              }
              buf += skip;
              buflen -= skip;
       }
       if (buflen < amount) {
              return 0;
       }
       *bufp = buf + amount;
       *buflenp = buflen - amount;
       return buf;
}
static PRStatus CopyHostent ( struct hostent from,
char **  buf,
PRIntn *  bufsize,
_PRIPAddrConversion  conversion,
PRHostEnt to 
) [static]

Definition at line 516 of file prnetdb.c.

{
       PRIntn len, na;
       char **ap;

       if (conversion != _PRIPAddrNoConversion
                     && from->h_addrtype == AF_INET) {
              PR_ASSERT(from->h_length == 4);
              to->h_addrtype = PR_AF_INET6;
              to->h_length = 16;
       } else {
#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
              if (AF_INET6 == from->h_addrtype)
                     to->h_addrtype = PR_AF_INET6;
              else
#endif
                     to->h_addrtype = from->h_addrtype;
              to->h_length = from->h_length;
       }

       /* Copy the official name */
       if (!from->h_name) return PR_FAILURE;
       len = strlen(from->h_name) + 1;
       to->h_name = Alloc(len, buf, bufsize, 0);
       if (!to->h_name) return PR_FAILURE;
       memcpy(to->h_name, from->h_name, len);

       /* Count the aliases, then allocate storage for the pointers */
       if (!from->h_aliases) {
              na = 1;
       } else {
              for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
       }
       to->h_aliases = (char**)Alloc(
           na * sizeof(char*), buf, bufsize, sizeof(char**));
       if (!to->h_aliases) return PR_FAILURE;

       /* Copy the aliases, one at a time */
       if (!from->h_aliases) {
              to->h_aliases[0] = 0;
       } else {
              for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) {
                     len = strlen(*ap) + 1;
                     to->h_aliases[na] = Alloc(len, buf, bufsize, 0);
                     if (!to->h_aliases[na]) return PR_FAILURE;
                     memcpy(to->h_aliases[na], *ap, len);
              }
              to->h_aliases[na] = 0;
       }

       /* Count the addresses, then allocate storage for the pointers */
       for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */
       to->h_addr_list = (char**)Alloc(
           na * sizeof(char*), buf, bufsize, sizeof(char**));
       if (!to->h_addr_list) return PR_FAILURE;

       /* Copy the addresses, one at a time */
       for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) {
              to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
              if (!to->h_addr_list[na]) return PR_FAILURE;
              if (conversion != _PRIPAddrNoConversion
                            && from->h_addrtype == AF_INET) {
                     if (conversion == _PRIPAddrIPv4Mapped) {
                            MakeIPv4MappedAddr(*ap, to->h_addr_list[na]);
                     } else {
                            PR_ASSERT(conversion == _PRIPAddrIPv4Compat);
                            MakeIPv4CompatAddr(*ap, to->h_addr_list[na]);
                     }
              } else {
                     memcpy(to->h_addr_list[na], *ap, to->h_length);
              }
       }
       to->h_addr_list[na] = 0;
       return PR_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus CopyProtoent ( struct protoent from,
char *  buf,
PRIntn  bufsize,
PRProtoEnt to 
) [static]

Definition at line 602 of file prnetdb.c.

{
       PRIntn len, na;
       char **ap;

       /* Do the easy stuff */
       to->p_num = from->p_proto;

       /* Copy the official name */
       if (!from->p_name) return PR_FAILURE;
       len = strlen(from->p_name) + 1;
       to->p_name = Alloc(len, &buf, &bufsize, 0);
       if (!to->p_name) return PR_FAILURE;
       memcpy(to->p_name, from->p_name, len);

       /* Count the aliases, then allocate storage for the pointers */
       for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
       to->p_aliases = (char**)Alloc(
           na * sizeof(char*), &buf, &bufsize, sizeof(char**));
       if (!to->p_aliases) return PR_FAILURE;

       /* Copy the aliases, one at a time */
       for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) {
              len = strlen(*ap) + 1;
              to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0);
              if (!to->p_aliases[na]) return PR_FAILURE;
              memcpy(to->p_aliases[na], *ap, len);
       }
       to->p_aliases[na] = 0;

       return PR_SUCCESS;
}

Here is the call graph for this function:

static struct protoent* getprotobyname_r ( const char *  name) [static, read]

Definition at line 1187 of file prnetdb.c.

{
#ifdef XP_OS2_VACPP
       return getprotobyname((char *)name);
#else
       return getprotobyname(name);
#endif
} /* getprotobyname_r */
static struct protoent* getprotobynumber_r ( PRInt32  number) [static, read]

Definition at line 1196 of file prnetdb.c.

{
       return getprotobynumber(number);
} /* getprotobynumber_r */
static void MakeIPv4CompatAddr ( const char *  v4,
char *  v6 
) [static]

Definition at line 506 of file prnetdb.c.

{
    memset(v6, 0, 12);
    memcpy(v6 + 12, v4, 4);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void MakeIPv4MappedAddr ( const char *  v4,
char *  v6 
) [static]

Definition at line 496 of file prnetdb.c.

{
    memset(v6, 0, 10);
    memset(v6 + 10, 0xff, 2);
    memcpy(v6 + 12, v4, 4);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRAddrInfo* pr_GetAddrInfoByNameFB ( const char *  hostname,
PRUint16  af,
PRIntn  flags 
) [static]

Definition at line 2052 of file prnetdb.c.

{
    PRStatus rv;
    PRAddrInfoFB *ai;
    /* fallback on PR_GetHostByName */
    ai = PR_NEW(PRAddrInfoFB);
    if (!ai) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        return NULL;
    }
    rv = PR_GetHostByName(hostname, ai->buf, sizeof ai->buf, &ai->hostent);
    if (rv == PR_FAILURE) {
        PR_Free(ai);
        return NULL;
    }
    ai->has_cname = !(flags & PR_AI_NOCANONNAME);

    return (PRAddrInfo *) ai;
}

Here is the caller graph for this function:

Definition at line 672 of file prnetdb.c.

{
       struct hostent *h;
       PRStatus rv = PR_FAILURE;
#if defined(_PR_HAVE_GETHOST_R)
    char localbuf[PR_NETDB_BUF_SIZE];
    char *tmpbuf;
    struct hostent tmphe;
    int h_err;
#endif

    if (!_pr_initialized) _PR_ImplicitInitialization();

#if defined(_PR_HAVE_GETHOST_R)
    tmpbuf = localbuf;
    if (bufsize > sizeof(localbuf))
    {
        tmpbuf = (char *)PR_Malloc(bufsize);
        if (NULL == tmpbuf)
        {
            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
            return rv;
        }
    }
#endif

       LOCK_DNS();

#ifdef XP_OS2_VACPP
       h = GETHOSTBYNAME((char *)name);
#else
       h = GETHOSTBYNAME(name);
#endif
    
       if (NULL == h)
       {
           PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
       }
       else
       {
              _PRIPAddrConversion conversion = _PRIPAddrNoConversion;
              rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
              if (PR_SUCCESS != rv)
                  PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
       }
       UNLOCK_DNS();
#if defined(_PR_HAVE_GETHOST_R)
    if (tmpbuf != localbuf)
        PR_Free(tmpbuf);
#endif
       return rv;
}

Here is the call graph for this function:

PR_IMPLEMENT ( PRIntn  )

Definition at line 1393 of file prnetdb.c.

{
    void *addr = hostEnt->h_addr_list[enumIndex++];
    memset(address, 0, sizeof(PRNetAddr));
    if (NULL == addr) enumIndex = 0;
    else
    {
        address->raw.family = hostEnt->h_addrtype;
        if (PR_AF_INET6 == hostEnt->h_addrtype)
        {
            address->ipv6.port = htons(port);
              address->ipv6.flowinfo = 0;
              address->ipv6.scope_id = 0;
            memcpy(&address->ipv6.ip, addr, hostEnt->h_length);
        }
        else
        {
            PR_ASSERT(AF_INET == hostEnt->h_addrtype);
            address->inet.port = htons(port);
            memcpy(&address->inet.ip, addr, hostEnt->h_length);
        }
    }
    return enumIndex;
}  /* PR_EnumerateHostEnt */

Here is the call graph for this function:

Definition at line 1871 of file prnetdb.c.

{
    PRUint8 *dstp;
    dstp = v6addr->pr_s6_addr;
    memset(dstp, 0, 10);
    memset(dstp + 10, 0xff, 2);
    memcpy(dstp + 12,(char *) &v4addr, 4);
}

Here is the call graph for this function:

Definition at line 1880 of file prnetdb.c.

{ return ntohs(n); }

Definition at line 1881 of file prnetdb.c.

{ return ntohl(n); }

Definition at line 1884 of file prnetdb.c.

{
#ifdef IS_BIG_ENDIAN
    return n;
#else
    PRUint64 tmp;
    PRUint32 hi, lo;
    LL_L2UI(lo, n);
    LL_SHR(tmp, n, 32);
    LL_L2UI(hi, tmp);
    hi = PR_ntohl(hi);
    lo = PR_ntohl(lo);
    LL_UI2L(n, lo);
    LL_SHL(n, n, 32);
    LL_UI2L(tmp, hi);
    LL_ADD(n, n, tmp);
    return n;
#endif
}  /* ntohll */

Definition at line 2074 of file prnetdb.c.

{
    /* restrict input to supported values */
    if ((af != PR_AF_INET && af != PR_AF_UNSPEC) ||
        (flags & ~ PR_AI_NOCANONNAME) != PR_AI_ADDRCONFIG) {
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
        return NULL;
    }

    if (!_pr_initialized) _PR_ImplicitInitialization();

#if !defined(_PR_HAVE_GETADDRINFO)
    return pr_GetAddrInfoByNameFB(hostname, af, flags);
#else
#if defined(_PR_INET6_PROBE)
    if (!_pr_ipv6_is_present) {
        return pr_GetAddrInfoByNameFB(hostname, af, flags);
    }
#endif
    {
        PRADDRINFO *res, hints;
        PRStatus rv;

        /*
         * we assume a RFC 2553 compliant getaddrinfo.  this may at some
         * point need to be customized as platforms begin to adopt the
         * RFC 3493.
         */

        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = (flags & PR_AI_NOCANONNAME) ? 0: AI_CANONNAME;
        hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC;

        /*
         * it is important to select a socket type in the hints, otherwise we
         * will get back repetitive entries: one for each socket type.  since
         * we do not expose ai_socktype through our API, it is okay to do this
         * here.  the application may still choose to create a socket of some
         * other type.
         */
        hints.ai_socktype = SOCK_STREAM;

        rv = GETADDRINFO(hostname, NULL, &hints, &res);
        if (rv == 0)
            return (PRAddrInfo *) res;

        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv);
    }
    return NULL;
#endif
}

Here is the call graph for this function:

PR_IMPLEMENT ( void )

Definition at line 2142 of file prnetdb.c.

{
#if defined(_PR_HAVE_GETADDRINFO)
    PRADDRINFO *ai;
#if defined(_PR_INET6_PROBE)
    if (!_pr_ipv6_is_present) {
        /* using PRAddrInfoFB */
        PRIntn iter = (PRIntn)(PRPtrdiff) iterPtr;
        iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
        if (iter < 0)
            iter = 0;
        return (void *)(PRPtrdiff) iter;
    }
#endif

    if (iterPtr)
        ai = ((PRADDRINFO *) iterPtr)->ai_next;
    else
        ai = (PRADDRINFO *) base;

    if (ai) {
        /* copy sockaddr to PRNetAddr */
        memcpy(result, ai->ai_addr, ai->ai_addrlen);
        result->raw.family = ai->ai_addr->sa_family;
        if (ai->ai_addrlen < sizeof(PRNetAddr))
            memset(((char*)result)+ai->ai_addrlen, 0, sizeof(PRNetAddr) - ai->ai_addrlen);

        if (result->raw.family == PR_AF_INET)
            result->inet.port = htons(port);
        else
            result->ipv6.port = htons(port);
    }

    return ai;
#else
    /* using PRAddrInfoFB */
    PRIntn iter = (PRIntn) iterPtr;
    iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
    if (iter < 0)
        iter = 0;
    return (void *) iter;
#endif
}

Here is the call graph for this function:

PR_IMPLEMENT ( const char *  )

Definition at line 2189 of file prnetdb.c.

{
#if defined(_PR_HAVE_GETADDRINFO)
#if defined(_PR_INET6_PROBE)
    if (!_pr_ipv6_is_present) {
        const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
        return fb->has_cname ? fb->hostent.h_name : NULL;
    } 
#endif
    return ((const PRADDRINFO *) ai)->ai_canonname;
#else
    const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
    return fb->has_cname ? fb->hostent.h_name : NULL;
#endif
}

Definition at line 1497 of file prnetdb.c.

{
    if (addr->raw.family == PR_AF_INET6) {
        if (val == PR_IpAddrAny) {
                     if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
              return PR_TRUE;
                     } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
                                   && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
                                                 == htonl(INADDR_ANY)) {
              return PR_TRUE;
                     }
        } else if (val == PR_IpAddrLoopback) {
            if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
              return PR_TRUE;
                     } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
                                   && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
                                                 == htonl(INADDR_LOOPBACK)) {
              return PR_TRUE;
                     }
        } else if (val == PR_IpAddrV4Mapped
                && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) {
            return PR_TRUE;
        }
    } else {
        if (addr->raw.family == AF_INET) {
            if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
                return PR_TRUE;
            } else if (val == PR_IpAddrLoopback
                    && addr->inet.ip == htonl(INADDR_LOOPBACK)) {
                return PR_TRUE;
            }
        }
    }
    return PR_FALSE;
}

Here is the caller graph for this function:

static int StringToV6Addr ( const char *  string,
PRIPv6Addr addr 
) [static]

Definition at line 1559 of file prnetdb.c.

{
    const unsigned char *s = (const unsigned char *)string;
    int section = 0;        /* index of the current section (a 16-bit
                             * piece of the address */
    int double_colon = -1;  /* index of the section after the first
                             * 16-bit group of zeros represented by
                             * the double colon */
    unsigned int val;
    int len;

    /* Handle initial (double) colon */
    if (*s == ':') {
        if (s[1] != ':') return 0;
        s += 2;
        addr->pr_s6_addr16[0] = 0;
        section = double_colon = 1;
    }

    while (*s) {
        if (section == 8) return 0; /* too long */
        if (*s == ':') {
            if (double_colon != -1) return 0; /* two double colons */
            addr->pr_s6_addr16[section++] = 0;
            double_colon = section;
            s++;
            continue;
        }
        for (len = val = 0; len < 4 && index_hex[*s] != XX; len++) {
            val = (val << 4) + index_hex[*s++];
        }
        if (*s == '.') {
            if (len == 0) return 0; /* nothing between : and . */
            break;
        }
        if (*s == ':') {
            s++;
            if (!*s) return 0; /* cannot end with single colon */
        } else if (*s) {
            return 0; /* bad character */
        }
        addr->pr_s6_addr16[section++] = htons((unsigned short)val);
    }
    
    if (*s == '.') {
        /* Have a trailing v4 format address */
        if (section > 6) return 0; /* not enough room */

        /*
         * The number before the '.' is decimal, but we parsed it
         * as hex.  That means it is in BCD.  Check it for validity
         * and convert it to binary.
         */
        if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0;
        val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf);
        addr->pr_s6_addr[2 * section] = val;

        s++;
        val = index_hex[*s++];
        if (val > 9) return 0;
        while (*s >= '0' && *s <= '9') {
            val = val * 10 + *s++ - '0';
            if (val > 255) return 0;
        }
        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
        addr->pr_s6_addr[2 * section + 1] = val;
        section++;

        s++;
        val = index_hex[*s++];
        if (val > 9) return 0;
        while (*s >= '0' && *s <= '9') {
            val = val * 10 + *s++ - '0';
            if (val > 255) return 0;
        }
        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
        addr->pr_s6_addr[2 * section] = val;

        s++;
        val = index_hex[*s++];
        if (val > 9) return 0;
        while (*s >= '0' && *s <= '9') {
            val = val * 10 + *s++ - '0';
            if (val > 255) return 0;
        }
        if (*s) return 0; /* must have exactly 4 decimal numbers */
        addr->pr_s6_addr[2 * section + 1] = val;
        section++;
    }
    
    if (double_colon != -1) {
        /* Stretch the double colon */
        int tosection;
        int ncopy = section - double_colon;
        for (tosection = 7; ncopy--; tosection--) {
            addr->pr_s6_addr16[tosection] = 
                addr->pr_s6_addr16[double_colon + ncopy];
        }
        while (tosection >= double_colon) {
            addr->pr_s6_addr16[tosection--] = 0;
        }
    } else if (section != 8) {
        return 0; /* too short */
    }
    return 1;
}
static const char* V6AddrToString ( const PRIPv6Addr addr,
char *  buf,
PRUint32  size 
) [static]

Definition at line 1675 of file prnetdb.c.

{
#define STUFF(c) do { \
    if (!size--) return NULL; \
    *buf++ = (c); \
} while (0)

    int double_colon = -1;          /* index of the first 16-bit
                                     * group of zeros represented
                                     * by the double colon */
    int double_colon_length = 1;    /* use double colon only if
                                     * there are two or more 16-bit
                                     * groups of zeros */
    int zero_length;
    int section;
    unsigned int val;
    const char *bufcopy = buf;

    /* Scan to find the placement of the double colon */
    for (section = 0; section < 8; section++) {
        if (addr->pr_s6_addr16[section] == 0) {
            zero_length = 1;
            section++;
            while (section < 8 && addr->pr_s6_addr16[section] == 0) {
                zero_length++;
                section++;
            }
            /* Select the longest sequence of zeros */
            if (zero_length > double_colon_length) {
                double_colon = section - zero_length;
                double_colon_length = zero_length;
            }
        }
    }

    /* Now start converting to a string */
    section = 0;

    if (double_colon == 0) {
        if (double_colon_length == 6 ||
            (double_colon_length == 5 && addr->pr_s6_addr16[5] == 0xffff)) {
            /* ipv4 format address */
            STUFF(':');
            STUFF(':');
            if (double_colon_length == 5) {
                STUFF('f');
                STUFF('f');
                STUFF('f');
                STUFF('f');
                STUFF(':');
            }
            if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0');
            if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0');
            STUFF(addr->pr_s6_addr[12]%10 + '0');
            STUFF('.');
            if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0');
            if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0');
            STUFF(addr->pr_s6_addr[13]%10 + '0');
            STUFF('.');
            if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0');
            if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0');
            STUFF(addr->pr_s6_addr[14]%10 + '0');
            STUFF('.');
            if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0');
            if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0');
            STUFF(addr->pr_s6_addr[15]%10 + '0');
            STUFF('\0');
            return bufcopy;
        }
    }

    while (section < 8) {
        if (section == double_colon) {
            STUFF(':');
            STUFF(':');
            section += double_colon_length;
            continue;
        }
        val = ntohs(addr->pr_s6_addr16[section]);
        if (val > 0xfff) {
            STUFF(basis_hex[val >> 12]);
        }
        if (val > 0xff) {
            STUFF(basis_hex[(val >> 8) & 0xf]);
        }
        if (val > 0xf) {
            STUFF(basis_hex[(val >> 4) & 0xf]);
        }
        STUFF(basis_hex[val & 0xf]);
        section++;
        if (section < 8 && section != double_colon) STUFF(':');
    }
    STUFF('\0');
    return bufcopy;
#undef STUFF    
}

Variable Documentation

Definition at line 122 of file prnetdb.c.

Definition at line 78 of file prnetdb.c.

Initial value:
       {{{ 0, 0, 0, 0,
                                                                      0, 0, 0, 0,
                                                                      0, 0, 0, 0,
                                                                      0, 0, 0, 0 }}}

Definition at line 144 of file prnetdb.c.

Initial value:
 {{{ 0, 0, 0, 0,
                                                                             0, 0, 0, 0,
                                                                             0, 0, 0, 0,
                                                                             0, 0, 0, 0x1U }}}

Definition at line 149 of file prnetdb.c.

const char* basis_hex = "0123456789abcdef" [static]

Definition at line 1667 of file prnetdb.c.

const unsigned char index_hex[256] [static]
Initial value:
 {
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,XX,XX, XX,XX,XX,XX,
    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
}

Definition at line 1535 of file prnetdb.c.