/* * convertToIPv4NetAddr * This function converts an IPv4-mapped IPv6 address to an IPv4 address. * ::FFFF:X:X (32 are non zeros) or * ::X:X (32 are non zeros and rest are 0's) but NOT loopback address(::1) * Input : PRNetAddr * src_v6addr IPv6 address * Output : PRNetAddr * dst_v4addr IPv4 address */ static void convertToIPv4NetAddr(const PRNetAddr *src_v6addr, PRNetAddr *dst_v4addr) { PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family); // ::FFFF:X:X if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) { // IPv6 address is a union of 16*PRUint8 each of 1 byte (8 bits) // copy last 32 bits src_v6addr->ipv6.ip.pr_s6_addr32[3] or // copy last 4, 8 bits(1 byte). const PRUint8 *srcp = src_v6addr->ipv6.ip.pr_s6_addr; memcpy((char *)&dst_v4addr->inet.ip, srcp + 12, 4); dst_v4addr->inet.family = PR_AF_INET; dst_v4addr->raw.family = PR_AF_INET; } else if (!PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback) && (src_v6addr->ipv6.ip.pr_s6_addr32[0] == 0 && src_v6addr->ipv6.ip.pr_s6_addr32[1] == 0 && src_v6addr->ipv6.ip.pr_s6_addr32[2] == 0 && src_v6addr->ipv6.ip.pr_s6_addr32[3] != 0)) { // ::X:X (32 are non zeros and rest are 0's) dst_v4addr->inet.ip = src_v6addr->ipv6.ip.pr_s6_addr32[3]; dst_v4addr->inet.family = PR_AF_INET; dst_v4addr->raw.family = PR_AF_INET; } }
static PRStatus nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime to) { PRStatus status; PRNetAddr dst; nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; if (info == NULL) return PR_FAILURE; if (PR_NetAddrFamily(addr) == PR_AF_INET6 && PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) { const uint8_t *srcp; LOGDEBUG(("socks: converting ipv4-mapped ipv6 address to ipv4")); // copied from _PR_ConvertToIpv4NetAddr() PR_InitializeNetAddr(PR_IpAddrAny, 0, &dst); srcp = addr->ipv6.ip.pr_s6_addr; memcpy(&dst.inet.ip, srcp + 12, 4); dst.inet.family = PR_AF_INET; dst.inet.port = addr->ipv6.port; } else { memcpy(&dst, addr, sizeof(dst)); } info->SetDestinationAddr(&dst); info->SetConnectTimeout(to); do { status = info->DoHandshake(fd, -1); } while (status == PR_SUCCESS && !info->IsConnected()); return status; }
void nsServerSocket::IsLocal(bool *aIsLocal) { #if defined(XP_UNIX) // Unix-domain sockets are always local. if (mAddr.raw.family == PR_AF_LOCAL) { *aIsLocal = true; return; } #endif // If bound to loopback, this server socket only accepts local connections. *aIsLocal = PR_IsNetAddrType(&mAddr, PR_IpAddrLoopback); }
NS_IMETHODIMP nsLDAPConnection::OnLookupComplete(nsICancelable *aRequest, nsIDNSRecord *aRecord, nsresult aStatus) { nsresult rv = NS_OK; if (aRecord) { // Build mResolvedIP list // mResolvedIP.Truncate(); PRInt32 index = 0; char addrbuf[64]; PRNetAddr addr; while (NS_SUCCEEDED(aRecord->GetNextAddr(0, &addr))) { // We can only use v4 addresses // PRBool v4mapped = PR_FALSE; if (addr.raw.family == PR_AF_INET6) v4mapped = PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped); if (addr.raw.family == PR_AF_INET || v4mapped) { // If there are more IPs in the list, we separate them with // a space, as supported/used by the LDAP C-SDK. // if (index++) mResolvedIP.Append(' '); // Convert the IPv4 address to a string, and append it to our // list of IPs. Strip leading '::FFFF:' (the IPv4-mapped-IPv6 // indicator) if present. // PR_NetAddrToString(&addr, addrbuf, sizeof(addrbuf)); if ((addrbuf[0] == ':') && (strlen(addrbuf) > 7)) mResolvedIP.Append(addrbuf+7); else mResolvedIP.Append(addrbuf); } } } if (NS_FAILED(aStatus)) { // The DNS service failed, lets pass something reasonable // back to the listener. // switch (aStatus) { case NS_ERROR_OUT_OF_MEMORY: case NS_ERROR_UNKNOWN_HOST: case NS_ERROR_FAILURE: case NS_ERROR_OFFLINE: rv = aStatus; break; default: rv = NS_ERROR_UNEXPECTED; break; } } else if (!mResolvedIP.Length()) { // We have no host resolved, that is very bad, and should most // likely have been caught earlier. // NS_ERROR("nsLDAPConnection::OnStopLookup(): the resolved IP " "string is empty.\n"); rv = NS_ERROR_UNKNOWN_HOST; } else { // We've got the IP(s) for the hostname, now lets setup the // LDAP connection using this information. Note that if the // LDAP server returns a referral, the C-SDK will perform a // new, synchronous DNS lookup, which might hang (but hopefully // if we've come this far, DNS is working properly). // mConnectionHandle = ldap_init(mResolvedIP.get(), mPort == -1 ? LDAP_PORT : mPort); // Check that we got a proper connection, and if so, setup the // threading functions for this connection. // if ( !mConnectionHandle ) { rv = NS_ERROR_FAILURE; // LDAP C SDK API gives no useful error } else { #if defined(DEBUG_dmose) || defined(DEBUG_bienvenu) const int lDebug = 0; ldap_set_option(mConnectionHandle, LDAP_OPT_DEBUG_LEVEL, &lDebug); #endif // the C SDK currently defaults to v2. if we're to use v3, // tell it so. // int version; switch (mVersion) { case 2: break; case 3: version = LDAP_VERSION3; ldap_set_option(mConnectionHandle, LDAP_OPT_PROTOCOL_VERSION, &version); break; default: NS_ERROR("nsLDAPConnection::OnLookupComplete(): mVersion" " invalid"); } #ifdef MOZ_PSM // This code sets up the current connection to use PSM for SSL // functionality. Making this use libssldap instead for // non-browser user shouldn't be hard. extern nsresult nsLDAPInstallSSL(LDAP *ld, const char *aHostName); if (mSSL) { if (ldap_set_option(mConnectionHandle, LDAP_OPT_SSL, LDAP_OPT_ON) != LDAP_SUCCESS ) { NS_ERROR("nsLDAPConnection::OnStopLookup(): Error" " configuring connection to use SSL"); rv = NS_ERROR_UNEXPECTED; } rv = nsLDAPInstallSSL(mConnectionHandle, mDNSHost.get()); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPConnection::OnStopLookup(): Error" " installing secure LDAP routines for" " connection"); } } #endif } // Create a new runnable object, and increment the refcnt. The // thread will also hold a strong ref to the runnable, but we need // to make sure it doesn't get destructed until we are done with // all locking etc. in nsLDAPConnection::Release(). // mRunnable = new nsLDAPConnectionLoop(); NS_IF_ADDREF(mRunnable); if (!mRunnable || NS_FAILED(mRunnable->Init())) { rv = NS_ERROR_OUT_OF_MEMORY; } else { // Here we keep a weak reference in the runnable object to the // nsLDAPConnection ("this"). This avoids the problem where a // connection can't get destructed because of the new thread // keeping a strong reference to it. It also helps us know when // we need to exit the new thread: when we can't convert the weak // reference to a strong ref, we know that the nsLDAPConnection // object is gone, and we need to stop the thread running. // nsCOMPtr<nsILDAPConnection> conn = static_cast<nsILDAPConnection *>(this); mRunnable->mWeakConn = do_GetWeakReference(conn); // kick off a thread for result listening and marshalling // rv = NS_NewThread(getter_AddRefs(mThread), mRunnable); if (NS_FAILED(rv)) { rv = NS_ERROR_NOT_AVAILABLE; } // XXX(darin): We need to shutdown this thread at some point. // Otherwise, it will stick around until shutdown. } } // Drop the DNS request object, we no longer need it, and set the flag // indicating that DNS has finished. // mDNSRequest = 0; mDNSHost.Truncate(); // Call the listener, and then we can release our reference to it. // mInitListener->OnLDAPInit(this, rv); mInitListener = 0; return rv; }
int main(int argc, char **argv) #endif { const char *hostName = DEFAULT_HOST_NAME; PRHostEnt he, reversehe; char buf[PR_NETDB_BUF_SIZE]; char reversebuf[PR_NETDB_BUF_SIZE]; PRIntn idx; PRNetAddr addr; PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "h"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 0: /* naked */ hostName = opt->value; break; case 'h': /* Help message */ default: Help(); return 2; } } PL_DestroyOptState(opt); PR_STDIO_INIT(); outFile = PR_GetSpecialFD(PR_StandardError); if (PR_GetHostByName(hostName, buf, sizeof(buf), &he) == PR_FAILURE) { PR_fprintf(outFile, "PR_GetHostByName failed\n"); exit(1); } PrintHostent(&he); idx = 0; while (1) { idx = PR_EnumerateHostEnt(idx, &he, 0, &addr); if (idx == -1) { PR_fprintf(outFile, "PR_EnumerateHostEnt failed\n"); exit(1); } if (idx == 0) break; /* normal loop termination */ PR_fprintf(outFile, "reverse lookup\n"); if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf), &reversehe) == PR_FAILURE) { PR_fprintf(outFile, "PR_GetHostByAddr failed\n"); exit(1); } PrintHostent(&reversehe); } PR_fprintf(outFile, "PR_GetIPNodeByName with PR_AF_INET\n"); if (PR_GetIPNodeByName(hostName, PR_AF_INET, PR_AI_DEFAULT, buf, sizeof(buf), &he) == PR_FAILURE) { PR_fprintf(outFile, "PR_GetIPNodeByName failed\n"); exit(1); } PrintHostent(&he); PR_fprintf(outFile, "PR_GetIPNodeByName with PR_AF_INET6\n"); if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT, buf, sizeof(buf), &he) == PR_FAILURE) { PR_fprintf(outFile, "PR_GetIPNodeByName failed\n"); exit(1); } PrintHostent(&he); idx = 0; PR_fprintf(outFile, "PR_GetHostByAddr with PR_AF_INET6\n"); while (1) { idx = PR_EnumerateHostEnt(idx, &he, 0, &addr); if (idx == -1) { PR_fprintf(outFile, "PR_EnumerateHostEnt failed\n"); exit(1); } if (idx == 0) break; /* normal loop termination */ PR_fprintf(outFile, "reverse lookup\n"); if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf), &reversehe) == PR_FAILURE) { PR_fprintf(outFile, "PR_GetHostByAddr failed\n"); exit(1); } PrintHostent(&reversehe); } PR_fprintf(outFile, "PR_GetHostByAddr with PR_AF_INET6 done\n"); PR_StringToNetAddr("::1", &addr); if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_TRUE) { PR_fprintf(outFile, "addr should not be ipv4 mapped address\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } PR_StringToNetAddr("127.0.0.1", &addr); if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } PR_StringToNetAddr("::FFFF:127.0.0.1", &addr); if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_FALSE) { PR_fprintf(outFile, "addr should be ipv4 mapped address\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { PR_fprintf(outFile, "PR_InitializeNetAddr failed\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { PR_fprintf(outFile, "addr should be unspecified address\n"); exit(1); } if (PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &addr) == PR_FAILURE) { PR_fprintf(outFile, "PR_InitializeNetAddr failed\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, 0, &addr) == PR_FAILURE) { PR_fprintf(outFile, "PR_SetNetAddr failed\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { PR_fprintf(outFile, "addr should be unspecified address\n"); exit(1); } if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr) == PR_FAILURE) { PR_fprintf(outFile, "PR_SetNetAddr failed\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } addr.inet.family = PR_AF_INET; addr.inet.port = 0; addr.inet.ip = PR_htonl(PR_INADDR_ANY); if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { PR_fprintf(outFile, "addr should be unspecified address\n"); exit(1); } { char buf[256]; PR_NetAddrToString(&addr, buf, 256); PR_fprintf(outFile, "IPv4 INADDRANY: %s\n", buf); } addr.inet.family = PR_AF_INET; addr.inet.port = 0; addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } { char buf[256]; PR_NetAddrToString(&addr, buf, 256); PR_fprintf(outFile, "IPv4 LOOPBACK: %s\n", buf); } if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { PR_fprintf(outFile, "PR_SetNetAddr failed\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { PR_fprintf(outFile, "addr should be unspecified address\n"); exit(1); } { char buf[256]; PR_NetAddrToString(&addr, buf, 256); PR_fprintf(outFile, "IPv6 INADDRANY: %s\n", buf); } if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, 0, &addr) == PR_FAILURE) { PR_fprintf(outFile, "PR_SetNetAddr failed\n"); exit(1); } if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { PR_fprintf(outFile, "addr should be loopback address\n"); exit(1); } { char buf[256]; PR_NetAddrToString(&addr, buf, 256); PR_fprintf(outFile, "IPv6 LOOPBACK: %s\n", buf); } { PRIPv6Addr v6addr; char tmp_buf[256]; PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr); PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &v6addr); PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr); addr.ipv6.ip = v6addr; PR_NetAddrToString(&addr, tmp_buf, 256); PR_fprintf(outFile, "IPv4-mapped IPv6 LOOPBACK: %s\n", tmp_buf); } PR_fprintf(outFile, "PASS\n"); return 0; }