michael@0: /* vim: et ts=2 sw=2 tw=80 michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsNetAddr.h" michael@0: #include "nsString.h" michael@0: #include "mozilla/net/DNS.h" michael@0: michael@0: using namespace mozilla::net; michael@0: michael@0: NS_IMPL_ISUPPORTS(nsNetAddr, nsINetAddr) michael@0: michael@0: /* Makes a copy of |addr| */ michael@0: nsNetAddr::nsNetAddr(NetAddr* addr) michael@0: { michael@0: NS_ASSERTION(addr, "null addr"); michael@0: mAddr = *addr; michael@0: } michael@0: michael@0: /* readonly attribute unsigned short family; */ michael@0: NS_IMETHODIMP nsNetAddr::GetFamily(uint16_t *aFamily) michael@0: { michael@0: switch(mAddr.raw.family) { michael@0: case AF_INET: michael@0: *aFamily = nsINetAddr::FAMILY_INET; michael@0: break; michael@0: case AF_INET6: michael@0: *aFamily = nsINetAddr::FAMILY_INET6; michael@0: break; michael@0: #if defined(XP_UNIX) michael@0: case AF_LOCAL: michael@0: *aFamily = nsINetAddr::FAMILY_LOCAL; michael@0: break; michael@0: #endif michael@0: default: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute AUTF8String address; */ michael@0: NS_IMETHODIMP nsNetAddr::GetAddress(nsACString & aAddress) michael@0: { michael@0: switch(mAddr.raw.family) { michael@0: /* PR_NetAddrToString can handle INET and INET6, but not LOCAL. */ michael@0: case AF_INET: michael@0: aAddress.SetCapacity(kIPv4CStrBufSize); michael@0: NetAddrToString(&mAddr, aAddress.BeginWriting(), kIPv4CStrBufSize); michael@0: aAddress.SetLength(strlen(aAddress.BeginReading())); michael@0: break; michael@0: case AF_INET6: michael@0: aAddress.SetCapacity(kIPv6CStrBufSize); michael@0: NetAddrToString(&mAddr, aAddress.BeginWriting(), kIPv6CStrBufSize); michael@0: aAddress.SetLength(strlen(aAddress.BeginReading())); michael@0: break; michael@0: #if defined(XP_UNIX) michael@0: case AF_LOCAL: michael@0: aAddress.Assign(mAddr.local.path); michael@0: break; michael@0: #endif michael@0: // PR_AF_LOCAL falls through to default when not XP_UNIX michael@0: default: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute unsigned short port; */ michael@0: NS_IMETHODIMP nsNetAddr::GetPort(uint16_t *aPort) michael@0: { michael@0: switch(mAddr.raw.family) { michael@0: case AF_INET: michael@0: *aPort = ntohs(mAddr.inet.port); michael@0: break; michael@0: case AF_INET6: michael@0: *aPort = ntohs(mAddr.inet6.port); michael@0: break; michael@0: #if defined(XP_UNIX) michael@0: case AF_LOCAL: michael@0: // There is no port number for local / connections. michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: #endif michael@0: default: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute unsigned long flow; */ michael@0: NS_IMETHODIMP nsNetAddr::GetFlow(uint32_t *aFlow) michael@0: { michael@0: switch(mAddr.raw.family) { michael@0: case AF_INET6: michael@0: *aFlow = ntohl(mAddr.inet6.flowinfo); michael@0: break; michael@0: case AF_INET: michael@0: #if defined(XP_UNIX) michael@0: case AF_LOCAL: michael@0: #endif michael@0: // only for IPv6 michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: default: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute unsigned long scope; */ michael@0: NS_IMETHODIMP nsNetAddr::GetScope(uint32_t *aScope) michael@0: { michael@0: switch(mAddr.raw.family) { michael@0: case AF_INET6: michael@0: *aScope = ntohl(mAddr.inet6.scope_id); michael@0: break; michael@0: case AF_INET: michael@0: #if defined(XP_UNIX) michael@0: case AF_LOCAL: michael@0: #endif michael@0: // only for IPv6 michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: default: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute boolean isV4Mapped; */ michael@0: NS_IMETHODIMP nsNetAddr::GetIsV4Mapped(bool *aIsV4Mapped) michael@0: { michael@0: switch(mAddr.raw.family) { michael@0: case AF_INET6: michael@0: *aIsV4Mapped = IPv6ADDR_IS_V4MAPPED(&mAddr.inet6.ip); michael@0: break; michael@0: case AF_INET: michael@0: #if defined(XP_UNIX) michael@0: case AF_LOCAL: michael@0: #endif michael@0: // only for IPv6 michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: default: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsNetAddr::GetNetAddr(NetAddr *aResult) { michael@0: memcpy(aResult, &mAddr, sizeof(mAddr)); michael@0: return NS_OK; michael@0: } michael@0: