📄 prnetdb.c
字号:
else af = AF_INET;#elif defined(_PR_INET6) af = AF_INET6;#else af = AF_INET;#endif } else { PR_ASSERT(hostaddr->raw.family == AF_INET); af = AF_INET; } if (hostaddr->raw.family == PR_AF_INET6) {#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) if (af == AF_INET6) { addr = &hostaddr->ipv6.ip; addrlen = sizeof(hostaddr->ipv6.ip); } else#endif { PR_ASSERT(af == AF_INET); if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return rv; } tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *) &hostaddr->ipv6.ip); addr = &tmp_ip; addrlen = sizeof(tmp_ip); } } else { PR_ASSERT(hostaddr->raw.family == AF_INET); PR_ASSERT(af == AF_INET); addr = &hostaddr->inet.ip; addrlen = sizeof(hostaddr->inet.ip); }#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 /* Do not need to lock the DNS lock if getipnodebyaddr() is called */#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) h = getipnodebyaddr(addr, addrlen, af, &error_num);#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) if (_pr_ipv6_is_present == PR_TRUE) h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen, af, &error_num); else { LOCK_DNS(); h = GETHOSTBYADDR(addr, addrlen, af); }#else /* _PR_HAVE_GETIPNODEBYADDR */ LOCK_DNS();#ifdef XP_OS2_VACPP h = GETHOSTBYADDR((char *)addr, addrlen, af);#else h = GETHOSTBYADDR(addr, addrlen, af);#endif#endif /* _PR_HAVE_GETIPNODEBYADDR */ if (NULL == h) {#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) if (_pr_ipv6_is_present == PR_TRUE) PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); else PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());#else PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());#endif } else { _PRIPAddrConversion conversion = _PRIPAddrNoConversion; if (hostaddr->raw.family == PR_AF_INET6) { if (af == AF_INET) { if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*) &hostaddr->ipv6.ip)) { conversion = _PRIPAddrIPv4Mapped; } else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *) &hostaddr->ipv6.ip)) { conversion = _PRIPAddrIPv4Compat; } } } rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry); if (PR_SUCCESS != rv) { PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); }#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) freehostent(h);#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) if (_pr_ipv6_is_present == PR_TRUE) (*((_pr_freehostent_t)_pr_freehostent_fp))(h);#endif } /* Must match the convoluted logic above for LOCK_DNS() */#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) if (_pr_ipv6_is_present == PR_FALSE) UNLOCK_DNS();#else /* _PR_HAVE_GETIPNODEBYADDR */ UNLOCK_DNS();#endif /* _PR_HAVE_GETIPNODEBYADDR */#if defined(_PR_HAVE_GETHOST_R) if (tmpbuf != localbuf) PR_Free(tmpbuf);#endif return rv;}/******************************************************************************//* * Some systems define a reentrant version of getprotobyname(). Too bad * the signature isn't always the same. But hey, they tried. If there * is such a definition, use it. Otherwise, grab a lock and do it here. *//******************************************************************************/#if !defined(_PR_HAVE_GETPROTO_R)/* * This may seem like a silly thing to do, but the compiler SHOULD * complain if getprotobyname_r() is implemented on some system and * we're not using it. For sure these signatures are different than * any usable implementation. */static struct protoent *getprotobyname_r(const char* name){#ifdef XP_OS2_VACPP return getprotobyname((char *)name);#else return getprotobyname(name);#endif} /* getprotobyname_r */static struct protoent *getprotobynumber_r(PRInt32 number){ return getprotobynumber(number);} /* getprotobynumber_r */#endif /* !defined(_PR_HAVE_GETPROTO_R) */PR_IMPLEMENT(PRStatus) PR_GetProtoByName( const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result){ PRStatus rv = PR_SUCCESS;#if defined(_PR_HAVE_GETPROTO_R) struct protoent* res = (struct protoent*)result;#endif if (!_pr_initialized) _PR_ImplicitInitialization();#if defined(_PR_HAVE_GETPROTO_R_INT) { /* ** The protoent_data has a pointer as the first field. ** That implies the buffer better be aligned, and char* ** doesn't promise much. */ PRUptrdiff aligned = (PRUptrdiff)buffer; if (0 != (aligned & (sizeof(struct protoent_data*) - 1))) { aligned += sizeof(struct protoent_data*) - 1; aligned &= ~(sizeof(struct protoent_data*) - 1); buflen -= (aligned - (PRUptrdiff)buffer); buffer = (char*)aligned; } }#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */ if (PR_NETDB_BUF_SIZE > buflen) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; }#if defined(_PR_HAVE_GETPROTO_R_POINTER) if (NULL == getprotobyname_r(name, res, buffer, buflen)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; }#elif defined(_PR_HAVE_GETPROTO_R_INT) /* ** The buffer needs to be zero'd, and it should be ** at least the size of a struct protoent_data. */ memset(buffer, 0, buflen); if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; }#elif defined(_PR_HAVE_5_ARG_GETPROTO_R) /* The 5th argument for getprotobyname_r() cannot be NULL */ if (-1 == getprotobyname_r(name, res, buffer, buflen, &res)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; }#else /* do it the hard way */ { struct protoent *staticBuf; PR_Lock(_getproto_lock); staticBuf = getprotobyname_r(name); if (NULL == staticBuf) { rv = PR_FAILURE; PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); } else { rv = CopyProtoent(staticBuf, buffer, buflen, result); if (PR_FAILURE == rv) PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); } PR_Unlock(_getproto_lock); }#endif /* all that */ return rv;}PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber( PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result){ PRStatus rv = PR_SUCCESS;#if defined(_PR_HAVE_GETPROTO_R) struct protoent* res = (struct protoent*)result;#endif if (!_pr_initialized) _PR_ImplicitInitialization();#if defined(_PR_HAVE_GETPROTO_R_INT) { /* ** The protoent_data has a pointer as the first field. ** That implies the buffer better be aligned, and char* ** doesn't promise much. */ PRUptrdiff aligned = (PRUptrdiff)buffer; if (0 != (aligned & (sizeof(struct protoent_data*) - 1))) { aligned += sizeof(struct protoent_data*) - 1; aligned &= ~(sizeof(struct protoent_data*) - 1); buflen -= (aligned - (PRUptrdiff)buffer); buffer = (char*)aligned; } }#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */ if (PR_NETDB_BUF_SIZE > buflen) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; }#if defined(_PR_HAVE_GETPROTO_R_POINTER) if (NULL == getprotobynumber_r(number, res, buffer, buflen)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; }#elif defined(_PR_HAVE_GETPROTO_R_INT) /* ** The buffer needs to be zero'd for these OS's. */ memset(buffer, 0, buflen); if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; }#elif defined(_PR_HAVE_5_ARG_GETPROTO_R) /* The 5th argument for getprotobynumber_r() cannot be NULL */ if (-1 == getprotobynumber_r(number, res, buffer, buflen, &res)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; }#else /* do it the hard way */ { struct protoent *staticBuf; PR_Lock(_getproto_lock); staticBuf = getprotobynumber_r(number); if (NULL == staticBuf) { rv = PR_FAILURE; PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); } else { rv = CopyProtoent(staticBuf, buffer, buflen, result); if (PR_FAILURE == rv) PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); } PR_Unlock(_getproto_lock); }#endif /* all that crap */ return rv;}PRUintn _PR_NetAddrSize(const PRNetAddr* addr){ 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) else if (AF_UNIX == addr->raw.family) addrsize = sizeof(addr->local);#endif else addrsize = 0; return addrsize;} /* _PR_NetAddrSize */PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt( PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address){ 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 */PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr( PRNetAddrValue val, PRUint16 port, PRNetAddr *addr){ PRStatus rv = PR_SUCCESS; if (!_pr_initialized) _PR_ImplicitInitialization(); if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); addr->inet.family = AF_INET; addr->inet.port = htons(port); switch (val) { case PR_IpAddrNull: break; /* don't overwrite the address */ case PR_IpAddrAny: addr->inet.ip = htonl(INADDR_ANY); break; case PR_IpAddrLoopback: addr->inet.ip = htonl(INADDR_LOOPBACK); break; default: PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); rv = PR_FAILURE; } return rv;} /* PR_InitializeNetAddr */PR_IMPLEMENT(PRStatus) PR_SetNetAddr( PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr){ PRStatus rv = PR_SUCCESS; if (!_pr_initialized) _PR_ImplicitInitialization(); if (af == PR_AF_INET6) { if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6)); addr->ipv6.family = af; addr->ipv6.port = htons(port); addr->ipv6.flowinfo = 0; addr->ipv6.scope_id = 0; switch (val) { case PR_IpAddrNull: break; /* don't overwrite the address */ case PR_IpAddrAny: addr->ipv6.ip = _pr_in6addr_any; break; case PR_IpAddrLoopback: addr->ipv6.ip = _pr_in6addr_loopback; break; default: PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); rv = PR_FAILURE; } } else { if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); addr->inet.family = af; addr->inet.port = htons(port); switch (val) { case PR_IpAddrNull: break; /* don't overwrite the address */ case PR_IpAddrAny: addr->inet.ip = htonl(INADDR_ANY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -