📄 prnetdb.c
字号:
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_SetNetAddr */PR_IMPLEMENT(PRBool)PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val){ 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;}#ifndef _PR_INET6#define XX 127static const unsigned char index_hex[256] = { 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,};/* * StringToV6Addr() returns 1 if the conversion succeeds, * or 0 if the input is not a valid IPv6 address string. * (Same as inet_pton(AF_INET6, string, addr).) */static int StringToV6Addr(const char *string, PRIPv6Addr *addr){ 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;}#undef XX static const char *basis_hex = "0123456789abcdef";/* * V6AddrToString() returns a pointer to the buffer containing * the text string if the conversion succeeds, and NULL otherwise. * (Same as inet_ntop(AF_INET6, addr, buf, size), except that errno * is not set on failure.) */static const char *V6AddrToString( const PRIPv6Addr *addr, char *buf, PRUint32 size){#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 }#endif /* !_PR_INET6 */PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr){ PRStatus status = PR_SUCCESS; PRIntn rv;#if defined(_PR_INET6) rv = inet_pton(AF_INET6, string, &addr->ipv6.ip); if (1 == rv) { addr->raw.family = PR_AF_INET6; } else { PR_ASSERT(0 == rv); /* clean up after the failed inet_pton() call */ memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip)); rv = inet_pton(AF_INET, string, &addr->inet.ip); if (1 == rv) { addr->raw.family = AF_INET; } else { PR_ASSERT(0 == rv); PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); status = PR_FAILURE; } }#else /* _PR_INET6 */ rv = StringToV6Addr(string, &addr->ipv6.ip); if (1 == rv) { addr->raw.family = PR_AF_INET6; return PR_SUCCESS; } PR_ASSERT(0 == rv); /* clean up after the failed StringToV6Addr() call */ memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip)); addr->inet.family = AF_INET;#ifdef XP_OS2_VACPP addr->inet.ip = inet_addr((char *)string);#else addr->inet.ip = inet_addr(string);#endif if ((PRUint32) -1 == addr->inet.ip) { /* * The string argument is a malformed address string. */ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); status = PR_FAILURE; }#endif /* _PR_INET6 */ return status;}PR_IMPLEMENT(PRStatus) PR_NetAddrToString( const PRNetAddr *addr, char *string, PRUint32 size){ if (PR_AF_INET6 == addr->raw.family) {#if defined(_PR_INET6) if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))#else if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))#endif { /* the size of the result buffer is inadequate */ PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); return PR_FAILURE; } } else { if (size < 16) goto failed; if (AF_INET != addr->raw.family) goto failed; else { unsigned char *byte = (unsigned char*)&addr->inet.ip; PR_snprintf(string, size, "%u.%u.%u.%u", byte[0], byte[1], byte[2], byte[3]); } } return PR_SUCCESS;failed: PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE;} /* PR_NetAddrToString *//* * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr */PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr){ PRUint8 *dstp; dstp = v6addr->pr_s6_addr; memset(dstp, 0, 10); memset(dstp + 10, 0xff, 2); memcpy(dstp + 12,(char *) &v4addr, 4);}PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); }PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); }PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); }PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); }PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n){#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 */PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n){#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 = htonl(hi); lo = htonl(lo); LL_UI2L(n, lo); LL_SHL(n, n, 32); LL_UI2L(tmp, hi); LL_ADD(n, n, tmp); return n;#endif} /* htonll */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -