Exemplo n.º 1
0
int wifiAdapter(TCHAR *strAdapter)
{
    DWORD ret;
    ULONG buffLen = 0;

    if ((ret = GetAdaptersInfo(NULL, &buffLen)) != ERROR_BUFFER_OVERFLOW)
        return 0;

    IP_ADAPTER_INFO* pInfo = (IP_ADAPTER_INFO*) malloc(buffLen);

    if ((ret = GetAdaptersInfo(pInfo, &buffLen)) != ERROR_SUCCESS){
        free(pInfo);
        return 0;
    }

	ret = 0;
    while (pInfo){
		MultiByteToWideChar(CP_UTF8, 0, pInfo->AdapterName, -1, (LPWSTR) strAdapter, 200);
        if (IsWireless(strAdapter)){
			ret = 1;
            break;
        }

        pInfo = pInfo->Next;
    }

    free(pInfo);
    return ret;
}
Exemplo n.º 2
0
void CNetworkInterfaceLinux::WriteSettings(FILE* fw, NetworkAssignment assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode)
{
   if (assignment == NETWORK_DHCP)
   {
      fprintf(fw, "iface %s inet dhcp\n", GetName().c_str());
   }
   else if (assignment == NETWORK_STATIC)
   {
      fprintf(fw, "iface %s inet static\n", GetName().c_str());
      fprintf(fw, "  address %s\n", ipAddress.c_str());
      fprintf(fw, "  netmask %s\n", networkMask.c_str());
      fprintf(fw, "  gateway %s\n", defaultGateway.c_str());
   }

   if (assignment != NETWORK_DISABLED && IsWireless())
   {
      if (encryptionMode == ENC_NONE)
      {
         fprintf(fw, "  wireless-essid %s\n", essId.c_str());
      }
      else if (encryptionMode == ENC_WEP)
      {
         fprintf(fw, "  wireless-essid %s\n", essId.c_str());
         fprintf(fw, "  wireless-key s:%s\n", key.c_str());
      }
      else if (encryptionMode == ENC_WPA || encryptionMode == ENC_WPA2)
      {
         fprintf(fw, "  wpa-ssid %s\n", essId.c_str());
         fprintf(fw, "  wpa-psk %s\n", key.c_str());
         fprintf(fw, "  wpa-proto %s\n", encryptionMode == ENC_WPA ? "WPA" : "WPA2");
      }
   }

   if (assignment != NETWORK_DISABLED)
      fprintf(fw, "auto %s\n\n", GetName().c_str());
}
Exemplo n.º 3
0
std::vector<NetworkAccessPoint> CNetworkInterfaceLinux::GetAccessPoints(void)
{
   std::vector<NetworkAccessPoint> result;

   if (!IsWireless())
      return result;

#if defined(TARGET_LINUX)
   // Query the wireless extension's version number. It will help us when we
   // parse the resulting events
   struct iwreq iwr;
   char rangebuffer[sizeof(iw_range) * 2];    /* Large enough */
   struct iw_range*  range = (struct iw_range*) rangebuffer;

   memset(rangebuffer, 0, sizeof(rangebuffer));
   iwr.u.data.pointer = (caddr_t) rangebuffer;
   iwr.u.data.length = sizeof(rangebuffer);
   iwr.u.data.flags = 0;
   strncpy(iwr.ifr_name, GetName().c_str(), IFNAMSIZ);
   iwr.ifr_name[IFNAMSIZ - 1] = 0;
   if (ioctl(m_network->GetSocket(), SIOCGIWRANGE, &iwr) < 0)
   {
      CLog::Log(LOGWARNING, "%-8.16s  Driver has no Wireless Extension version information.",
         GetName().c_str());
      return result;
   }

   // Scan for wireless access points
   memset(&iwr, 0, sizeof(iwr));
   strncpy(iwr.ifr_name, GetName().c_str(), IFNAMSIZ);
   iwr.ifr_name[IFNAMSIZ - 1] = 0;
   if (ioctl(m_network->GetSocket(), SIOCSIWSCAN, &iwr) < 0)
   {
      // Triggering scanning is a privileged operation (root only)
      if (errno == EPERM)
         CLog::Log(LOGWARNING, "Cannot initiate wireless scan: ioctl[SIOCSIWSCAN]: %s. Try running as root", strerror(errno));
      else
         CLog::Log(LOGWARNING, "Cannot initiate wireless scan: ioctl[SIOCSIWSCAN]: %s", strerror(errno));
      return result;
   }

   // Get the results of the scanning. Three scenarios:
   //    1. There's not enough room in the result buffer (E2BIG)
   //    2. The scanning is not complete (EAGAIN) and we need to try again. We cap this with 15 seconds.
   //    3. We're good.
   int duration = 0; // ms
   unsigned char* res_buf = NULL;
   int res_buf_len = IW_SCAN_MAX_DATA;
   while (duration < 15000)
   {
      if (!res_buf)
         res_buf = (unsigned char*) malloc(res_buf_len);

      if (res_buf == NULL)
      {
         CLog::Log(LOGWARNING, "Cannot alloc memory for wireless scanning");
         return result;
      }

      strncpy(iwr.ifr_name, GetName().c_str(), IFNAMSIZ);
      iwr.ifr_name[IFNAMSIZ - 1] = 0;
      iwr.u.data.pointer = res_buf;
      iwr.u.data.length = res_buf_len;
      iwr.u.data.flags = 0;
      int x = ioctl(m_network->GetSocket(), SIOCGIWSCAN, &iwr);
      if (x == 0)
         break;

      if (errno == E2BIG && res_buf_len < 100000)
      {
         free(res_buf);
         res_buf = NULL;
         res_buf_len *= 2;
         CLog::Log(LOGDEBUG, "Scan results did not fit - trying larger buffer (%lu bytes)",
                        (unsigned long) res_buf_len);
      }
      else if (errno == EAGAIN)
      {
         usleep(250000); // sleep for 250ms
         duration += 250;
      }
      else
      {
         CLog::Log(LOGWARNING, "Cannot get wireless scan results: ioctl[SIOCGIWSCAN]: %s", strerror(errno));
         free(res_buf);
         return result;
      }
   }

   size_t len = iwr.u.data.length;           // total length of the wireless events from the scan results
   unsigned char* pos = res_buf;             // pointer to the current event (about 10 per wireless network)
   unsigned char* end = res_buf + len;       // marks the end of the scan results
   unsigned char* custom;                    // pointer to the event payload
   struct iw_event iwe_buf, *iwe = &iwe_buf; // buffer to hold individual events

   std::string essId;
   std::string macAddress;
   int signalLevel = 0;
   EncMode encryption = ENC_NONE;
   int channel = 0;

   while (pos + IW_EV_LCP_LEN <= end)
   {
      /* Event data may be unaligned, so make a local, aligned copy
       * before processing. */

      // copy event prefix (size of event minus IOCTL fixed payload)
      memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
      if (iwe->len <= IW_EV_LCP_LEN)
         break;

      // if the payload is nontrivial (i.e. > 16 octets) assume it comes after a pointer
      custom = pos + IW_EV_POINT_LEN;
      if (range->we_version_compiled > 18 &&
          (iwe->cmd == SIOCGIWESSID ||
           iwe->cmd == SIOCGIWENCODE ||
           iwe->cmd == IWEVGENIE ||
           iwe->cmd == IWEVCUSTOM))
      {
         /* Wireless extensions v19 removed the pointer from struct iw_point */
         char *data_pos = (char *) &iwe_buf.u.data.length;
         int data_len = data_pos - (char *) &iwe_buf;
         memcpy(data_pos, pos + IW_EV_LCP_LEN, sizeof(struct iw_event) - data_len);
      }
      else
      {
         // copy the rest of the event and point custom toward the payload offset
         memcpy(&iwe_buf, pos, sizeof(struct iw_event));
         custom += IW_EV_POINT_OFF;
      }

      // Interpret the payload based on event type. Each access point generates ~12 different events
      switch (iwe->cmd)
      {
         // Get access point MAC addresses
         case SIOCGIWAP:
         {
            // This event marks a new access point, so push back the old information
            if (!macAddress.empty())
               result.push_back(NetworkAccessPoint(essId, macAddress, signalLevel, encryption, channel));
            unsigned char* mac = (unsigned char*)iwe->u.ap_addr.sa_data;
            // macAddress is big-endian, write in byte chunks
            macAddress = StringUtils::Format("%02x-%02x-%02x-%02x-%02x-%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
            // Reset the remaining fields
            essId = "";
            encryption = ENC_NONE;
            signalLevel = 0;
            channel = 0;
            break;
         }

         // Get operation mode
         case SIOCGIWMODE:
         {
            // Ignore Ad-Hoc networks (1 is the magic number for this)
            if (iwe->u.mode == 1)
               macAddress = "";
            break;
         }

         // Get ESSID
         case SIOCGIWESSID:
         {
            char essid[IW_ESSID_MAX_SIZE+1];
            memset(essid, '\0', sizeof(essid));
            if ((custom) && (iwe->u.essid.length))
            {
               memcpy(essid, custom, iwe->u.essid.length);
               essId = essid;
            }
            break;
         }

         // Quality part of statistics
         case IWEVQUAL:
         {
            // u.qual.qual is scaled to a vendor-specific RSSI_Max, so use u.qual.level
            signalLevel = iwe->u.qual.level - 0x100; // and remember we use 8-bit arithmetic
            break;
         }

         // Get channel/frequency (Hz)
         // This gets called twice per network, what's the difference between the two?
         case SIOCGIWFREQ:
         {
            float freq = ((float)iwe->u.freq.m) * pow(10.0, iwe->u.freq.e);
            if (freq > 1000)
               channel = NetworkAccessPoint::FreqToChannel(freq);
            else
               channel = (int)freq; // Some drivers report channel instead of frequency
            break;
         }

         // Get encoding token & mode
         case SIOCGIWENCODE:
         {
            if (!(iwe->u.data.flags & IW_ENCODE_DISABLED) && encryption == ENC_NONE)
               encryption = ENC_WEP;
            break;
         }

         // Generic IEEE 802.11 information element (IE) for WPA, RSN, WMM, ...
         case IWEVGENIE:
         {
            int offset = 0;
            // Loop on each IE, each IE is minimum 2 bytes
            while (offset <= (iwe_buf.u.data.length - 2))
            {
               switch (custom[offset])
               {
                  case 0xdd: /* WPA1 */
                     if (encryption != ENC_WPA2)
                        encryption = ENC_WPA;
                     break;
                  case 0x30: /* WPA2 */
                     encryption = ENC_WPA2;
               }
               // Skip over this IE to the next one in the list
               offset += custom[offset+1] + 2;
            }
         }
      }

      pos += iwe->len;
   }

   if (!macAddress.empty())
      result.push_back(NetworkAccessPoint(essId, macAddress, signalLevel, encryption, channel));

   free(res_buf);
   res_buf = NULL;
#endif

   return result;
}
Exemplo n.º 4
0
void CPosixNetworkManager::FindNetworkInterfaces()
{
  m_connections.clear();

  FILE *fp = fopen("/proc/net/dev", "r");
  if (!fp)
    return;

  int n, linenum = 0;
  char   *line = NULL;
  size_t linel = 0;
  char   *interfaceName;
  bool   managed = CanManageConnections();

  while (getdelim(&line, &linel, '\n', fp) > 0)
  {
    // skip first two lines
    if (linenum++ < 2)
      continue;

    // search where the word begins
    interfaceName = line;
    while (isspace(*interfaceName))
      ++interfaceName;

    // read word until :
    n = strcspn(interfaceName, ": \t");
    interfaceName[n] = 0;

#if defined(TARGET_ANDROID)
    // only test ethX and wlanX interfaces,
    // anything else is non-standard and we do not care about it.
    if (strncmp(interfaceName, "eth", 3) != 0 && strncmp(interfaceName, "wlan", 4) != 0)
      continue;
#endif

    // make sure the device has ethernet encapsulation
    struct ifreq ifr;
    memset(&ifr, 0x00, sizeof(ifr));
    strcpy(ifr.ifr_name, interfaceName);
    std::string essid = "Wired";
    ConnectionType connection = NETWORK_CONNECTION_TYPE_WIRED;
    EncryptionType encryption = NETWORK_CONNECTION_ENCRYPTION_NONE;

    if (ioctl(m_socket, SIOCGIFHWADDR, &ifr) >= 0)
    {
#if defined(TARGET_ANDROID)
      // Android cannot SIOCSIWSCAN (permissions error)
      // So just flag as wifi with unknown encryption and use it.
      if (IsWireless(m_socket, interfaceName))
      {
        essid = "Wifi";
        connection = NETWORK_CONNECTION_TYPE_WIFI;
        encryption = NETWORK_CONNECTION_ENCRYPTION_UNKNOWN;
      }
#else
      if (IsWireless(m_socket, interfaceName))
      {
        // get the list of access points on this interface, try this 3 times
        int retryCount = 0;
        while (!FindWifiConnections(interfaceName) && retryCount < 3)
          retryCount++;
      }
      else
#endif
      {
        // and ignore loopback, we also include ARPHRD_80211 but that will only
        // apply if we are running on android.
        if ((ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER || ifr.ifr_hwaddr.sa_family == ARPHRD_80211)
           && !(ifr.ifr_flags & IFF_LOOPBACK))
        {
          char macaddress[1024] = {0};
          if (ioctl(m_socket, SIOCGIFHWADDR, &ifr) >= 0)
          {
            // format up 'wire.<mac address>.<interface name>
            sprintf(macaddress, "%02X:%02X:%02X:%02X:%02X:%02X",
              ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1],
              ifr.ifr_hwaddr.sa_data[2], ifr.ifr_hwaddr.sa_data[3],
              ifr.ifr_hwaddr.sa_data[4], ifr.ifr_hwaddr.sa_data[5]);
          }
          /*
          CLog::Log(LOGDEBUG, "CPosixNetworkManager::FindNetworkInterfaces, "
            "interfaceName(%s), macaddress(%s), essid(%s)",
            interfaceName, macaddress, essid.c_str());
          */
          m_connections.push_back(CConnectionPtr(new CPosixConnection(managed,
             m_socket, interfaceName, macaddress, essid.c_str(), connection, encryption, 100)));
        }
      }
    }
  }

  free(line);
  fclose(fp);
}