Exemplo n.º 1
0
int nr_praddr_to_transport_addr(const PRNetAddr *praddr,
                                nr_transport_addr *addr, int protocol,
                                int keep)
  {
    int _status;
    int r;
    struct sockaddr_in ip4;

    switch(praddr->raw.family) {
      case PR_AF_INET:
        ip4.sin_family = PF_INET;
        ip4.sin_addr.s_addr = praddr->inet.ip;
        ip4.sin_port = praddr->inet.port;
        if ((r = nr_sockaddr_to_transport_addr((sockaddr *)&ip4,
                                               sizeof(ip4),
                                               protocol, keep,
                                               addr)))
          ABORT(r);
        break;
      case PR_AF_INET6:
#if 0
        r = nr_sockaddr_to_transport_addr((sockaddr *)&praddr->raw,
          sizeof(struct sockaddr_in6),IPPROTO_UDP,keep,addr);
        break;
#endif
        ABORT(R_BAD_ARGS);
      default:
        MOZ_ASSERT(false);
        ABORT(R_BAD_ARGS);
    }

    _status=0;
 abort:
    return(_status);
  }
Exemplo n.º 2
0
static int
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
{
    int r,_status;
    PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL, tmpAddress = NULL;
    ULONG buflen;
    char munged_ifname[IFNAMSIZ];
    int n = 0;

    *count = 0;

    if (maxaddrs <= 0)
      ABORT(R_INTERNAL);

    /* Call GetAdaptersAddresses() twice.  First, just to get the buf length */

    buflen = 0;

    r = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, AdapterAddresses, &buflen);
    if (r != ERROR_BUFFER_OVERFLOW) {
      r_log(NR_LOG_STUN, LOG_ERR, "Error getting buf len from GetAdaptersAddresses()");
      ABORT(R_INTERNAL);
    }

    AdapterAddresses = (PIP_ADAPTER_ADDRESSES) RMALLOC(buflen);
    if (AdapterAddresses == NULL) {
      r_log(NR_LOG_STUN, LOG_ERR, "Error allocating buf for GetAdaptersAddresses()");
      ABORT(R_NO_MEMORY);
    }

    /* for real, this time */

    r = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, AdapterAddresses, &buflen);
    if (r != NO_ERROR) {
      r_log(NR_LOG_STUN, LOG_ERR, "Error getting addresses from GetAdaptersAddresses()");
      ABORT(R_INTERNAL);
    }

    /* Loop through the adapters */

    for (tmpAddress = AdapterAddresses; tmpAddress != NULL; tmpAddress = tmpAddress->Next) {
      char *c;

      if (tmpAddress->OperStatus != IfOperStatusUp)
        continue;

      snprintf(munged_ifname, IFNAMSIZ, "%S%c", tmpAddress->FriendlyName, 0);
      /* replace spaces with underscores */
      c = strchr(munged_ifname, ' ');
      while (c != NULL) {
        *c = '_';
         c = strchr(munged_ifname, ' ');
      }
      c = strchr(munged_ifname, '.');
      while (c != NULL) {
        *c = '+';
         c = strchr(munged_ifname, '.');
      }

      if ((tmpAddress->IfIndex != 0) || (tmpAddress->Ipv6IfIndex != 0)) {
        IP_ADAPTER_UNICAST_ADDRESS *u = 0;

        for (u = tmpAddress->FirstUnicastAddress; u != 0; u = u->Next) {
          SOCKET_ADDRESS *sa_addr = &u->Address;

          if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
              (sa_addr->lpSockaddr->sa_family == AF_INET6)) {
            if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, IPPROTO_UDP, 0, &(addrs[n].addr))))
                ABORT(r);
          }
          else {
            r_log(NR_LOG_STUN, LOG_DEBUG, "Unrecognized sa_family for adapteraddress %s",munged_ifname);
            continue;
          }

          strlcpy(addrs[n].addr.ifname, munged_ifname, sizeof(addrs[n].addr.ifname));
          /* TODO: (Bug 895793) Getting interface properties for Windows */
          addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
          addrs[n].interface.estimated_speed = 0;
          if (++n >= maxaddrs)
            goto done;
        }
      }
    }

   done:
    *count = n;
    _status = 0;

  abort:
    RFREE(AdapterAddresses);
    return _status;
}
Exemplo n.º 3
0
static int
stun_getifaddrs(nr_local_addr addrs[], int maxaddrs, int *count)
{
  int r,_status;
  struct ifaddrs* if_addrs_head=NULL;
  struct ifaddrs* if_addr;

  *count=0;

  if (getifaddrs(&if_addrs_head) == -1) {
    r_log(NR_LOG_STUN, LOG_ERR, "getifaddrs error e = %d", errno);
    ABORT(R_INTERNAL);
  }

  if_addr = if_addrs_head;

  while (if_addr && *count < maxaddrs) {
    /* This can be null */
    if (if_addr->ifa_addr) {
      switch (if_addr->ifa_addr->sa_family) {
        case AF_INET:
        case AF_INET6:
          if (r=nr_sockaddr_to_transport_addr(if_addr->ifa_addr, IPPROTO_UDP, 0, &(addrs[*count].addr))) {
            r_log(NR_LOG_STUN, LOG_ERR, "nr_sockaddr_to_transport_addr error r = %d", r);
          } else {
#if defined(LINUX) && !defined(ANDROID)
            struct ethtool_cmd ecmd;
            struct ifreq ifr;
            struct iwreq wrq;
            int e;
            int s = socket(AF_INET, SOCK_DGRAM, 0);

            strncpy(ifr.ifr_name, if_addr->ifa_name, sizeof(ifr.ifr_name));
            /* TODO (Bug 896851): interface property for Android */
            /* Getting ethtool for ethernet information. */
            ecmd.cmd = ETHTOOL_GSET;
            /* In/out param */
            ifr.ifr_data = (void*)&ecmd;

            e = ioctl(s, SIOCETHTOOL, &ifr);
            if (e == 0)
            {
               /* For wireless network, we won't get ethtool, it's a wired
                * connection */
               addrs[*count].interface.type = NR_INTERFACE_TYPE_WIRED;
#ifdef DONT_HAVE_ETHTOOL_SPEED_HI
               addrs[*count].interface.estimated_speed = ecmd.speed;
#else
               addrs[*count].interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
#endif
            }

            strncpy(wrq.ifr_name, if_addr->ifa_name, sizeof(wrq.ifr_name));
            e = ioctl(s, SIOCGIWRATE, &wrq);
            if (e == 0)
            {
               addrs[*count].interface.type = NR_INTERFACE_TYPE_WIFI;
               addrs[*count].interface.estimated_speed = wrq.u.bitrate.value / 1000;
            }

            close(s);

            if (if_addr->ifa_flags & IFF_POINTOPOINT)
            {
               addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
               /* TODO (Bug 896913): find backend network type of this VPN */
            }
#else
            addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
            addrs[*count].interface.estimated_speed = 0;
#endif
            strlcpy(addrs[*count].addr.ifname, if_addr->ifa_name, sizeof(addrs[*count].addr.ifname));
            ++(*count);
          }
          break;
        default:
          ;
      }
    }

    if_addr = if_addr->ifa_next;
  }

  _status=0;
abort:
  if (if_addrs_head) {
    freeifaddrs(if_addrs_head);
  }
  return(_status);
}
Exemplo n.º 4
0
static int
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
{
    int r, _status;
    PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL, tmpAddress = NULL;
    // recomended per https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
    static const ULONG initialBufLen = 15000;
    ULONG buflen = initialBufLen;
    char bin_hashed_ifname[NR_MD5_HASH_LENGTH];
    char hex_hashed_ifname[MAXIFNAME];
    int n = 0;

    *count = 0;

    if (maxaddrs <= 0)
      ABORT(R_BAD_ARGS);

    /* According to MSDN (see above) we have try GetAdapterAddresses() multiple times */
    for (n = 0; n < 5; n++) {
      AdapterAddresses = (PIP_ADAPTER_ADDRESSES) RMALLOC(buflen);
      if (AdapterAddresses == NULL) {
        r_log(NR_LOG_STUN, LOG_ERR, "Error allocating buf for GetAdaptersAddresses()");
        ABORT(R_NO_MEMORY);
      }

      r = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, AdapterAddresses, &buflen);
      if (r == NO_ERROR) {
        break;
      }
      r_log(NR_LOG_STUN, LOG_ERR, "GetAdaptersAddresses() returned error (%d)", r);
      RFREE(AdapterAddresses);
    }

    if (n >= 5) {
      r_log(NR_LOG_STUN, LOG_ERR, "5 failures calling GetAdaptersAddresses()");
      ABORT(R_INTERNAL);
    }

    n = 0;

    /* Loop through the adapters */

    for (tmpAddress = AdapterAddresses; tmpAddress != NULL; tmpAddress = tmpAddress->Next) {

      if (tmpAddress->OperStatus != IfOperStatusUp)
        continue;

      if ((tmpAddress->IfIndex != 0) || (tmpAddress->Ipv6IfIndex != 0)) {
        IP_ADAPTER_UNICAST_ADDRESS *u = 0;

        if(r=nr_crypto_md5((UCHAR *)tmpAddress->FriendlyName,
                           wcslen(tmpAddress->FriendlyName) * sizeof(wchar_t),
                           bin_hashed_ifname))
          ABORT(r);
        if(r=nr_bin2hex(bin_hashed_ifname, sizeof(bin_hashed_ifname),
          hex_hashed_ifname))
          ABORT(r);

        for (u = tmpAddress->FirstUnicastAddress; u != 0; u = u->Next) {
          SOCKET_ADDRESS *sa_addr = &u->Address;

          if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
              (sa_addr->lpSockaddr->sa_family == AF_INET6)) {
            if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, IPPROTO_UDP, 0, &(addrs[n].addr))))
                ABORT(r);
          }
          else {
            r_log(NR_LOG_STUN, LOG_DEBUG, "Unrecognized sa_family for address on adapter %lu", tmpAddress->IfIndex);
            continue;
          }

          strlcpy(addrs[n].addr.ifname, hex_hashed_ifname, sizeof(addrs[n].addr.ifname));
          if (tmpAddress->IfType == IF_TYPE_ETHERNET_CSMACD) {
            addrs[n].interface.type = NR_INTERFACE_TYPE_WIRED;
          } else if (tmpAddress->IfType == IF_TYPE_IEEE80211) {
            /* Note: this only works for >= Win Vista */
            addrs[n].interface.type = NR_INTERFACE_TYPE_WIFI;
          } else {
            addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
          }
#if (_WIN32_WINNT >= 0x0600)
          /* Note: only >= Vista provide link speed information */
          addrs[n].interface.estimated_speed = tmpAddress->TransmitLinkSpeed / 1000;
#else
          addrs[n].interface.estimated_speed = 0;
#endif
          if (++n >= maxaddrs)
            goto done;
        }
      }
    }

   done:
    *count = n;
    _status = 0;

  abort:
    RFREE(AdapterAddresses);
    return _status;
}