예제 #1
0
bool CNetAddr::IsIPv6() const
{
    return (!IsIPv4() && !IsTor() && !IsInternal());
}
예제 #2
0
bool CNetAddr::IsRFC5737() const
{
    return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
        (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
        (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
}
예제 #3
0
// get canonical identifier of an address' group
// no two connections will be attempted to addresses with the same group
std::vector<unsigned char> CNetAddr::GetGroup() const
{
    std::vector<unsigned char> vchRet;
    int nClass = NET_IPV6;
    int nStartByte = 0;
    int nBits = 16;

    // all local addresses belong to the same group
    if (IsLocal())
    {
        nClass = 255;
        nBits = 0;
    }
    // all internal-usage addresses get their own group
    if (IsInternal())
    {
        nClass = NET_INTERNAL;
        nStartByte = sizeof(g_internal_prefix);
        nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8;
    }
    // all other unroutable addresses belong to the same group
    else if (!IsRoutable())
    {
        nClass = NET_UNROUTABLE;
        nBits = 0;
    }
    // for IPv4 addresses, '1' + the 16 higher-order bits of the IP
    // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
    else if (IsIPv4() || IsRFC6145() || IsRFC6052())
    {
        nClass = NET_IPV4;
        nStartByte = 12;
    }
    // for 6to4 tunnelled addresses, use the encapsulated IPv4 address
    else if (IsRFC3964())
    {
        nClass = NET_IPV4;
        nStartByte = 2;
    }
    // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address
    else if (IsRFC4380())
    {
        vchRet.push_back(NET_IPV4);
        vchRet.push_back(GetByte(3) ^ 0xFF);
        vchRet.push_back(GetByte(2) ^ 0xFF);
        return vchRet;
    }
    else if (IsTor())
    {
        nClass = NET_TOR;
        nStartByte = 6;
        nBits = 4;
    }
    // for he.net, use /36 groups
    else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
        nBits = 36;
    // for the rest of the IPv6 network, use /32 groups
    else
        nBits = 32;

    vchRet.push_back(nClass);
    while (nBits >= 8)
    {
        vchRet.push_back(GetByte(15 - nStartByte));
        nStartByte++;
        nBits -= 8;
    }
    if (nBits > 0)
        vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));

    return vchRet;
}
예제 #4
0
bool CNetAddr::IsRFC6598() const
{
    return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127;
}
예제 #5
0
bool CNetAddr::IsRFC3927() const
{
    return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
}
예제 #6
0
bool CNetAddr::IsRFC2544() const
{
    return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19);
}
예제 #7
0
bool CNetAddr::IsMulticast() const
{
    return    (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0)
           || (GetByte(15) == 0xFF);
}
예제 #8
0
const char* sockAddrBase::ToString(bool includePort /*true*/) const
{
  in_port_t port = includePort ? Port() : 0;

  if (IsIPv4())
  {
    if (port == 0)
      return Ip4ToString(getIPv4Storage()->sin_addr);
    else
      return Ip4ToString(getIPv4Storage()->sin_addr, port);
  }
  else if (IsIPv6())
  {
    const sockaddr_in6 *storage = getIPv6Storage();

    if (storage->sin6_scope_id == 0 && !port)
    {
      // Just IPv6 address
      char *buffer;
      size_t bufsize = GetSmallTLSBuffer(&buffer);
      if (!bufsize)
        return "<memerror>";
      if (!inet_ntop(AF_INET6, &storage->sin6_addr, buffer, bufsize))
        return "<Invalid Address>";
      return buffer;
    }
    else
    {
      // composite address
      char ifNameBuf[IF_NAMESIZE];
      char addrStrBuf[INET6_ADDRSTRLEN];
      const char *ifName = NULL;
      const char *addrStr = NULL;

      if (storage->sin6_scope_id)
      {
        ifName = if_indextoname(storage->sin6_scope_id, ifNameBuf);
        if (!ifName)
          ifName = "???";
      }

      addrStr = inet_ntop(AF_INET6, &storage->sin6_addr, addrStrBuf, sizeof(addrStrBuf));
      if (!addrStr)
        addrStr = "<Invalid IPv6>";

      if (port)
      {
        if (ifName)
          return FormatShortStr("[%s%%%s]:%d", addrStr, ifName, (int)port);
        else
          return FormatShortStr("[%s]:%d", addrStr, (int)port);
      }
      else
      {
        if (ifName)
          return FormatShortStr("%s%%%s", addrStr, ifName);
        else
        {
          LogVerify(false); // should never happen
          return FormatShortStr("%s", addrStr);
        }
      }
    }
  }
  else
    return "<Invalid Address>";
}