Beispiel #1
0
static double
get_stats_discarded_code(void *arg)
{
	int has_range = 1;

	if (iw_get_range_info(skfd, arg, &range) < 0) {
		has_range = 0;
	}

	if (iw_get_stats(skfd, arg, &stats, &range, has_range) < 0) {
		xsg_debug("get_stats_discarded_code: UNKNOWN");
		return DNAN;
	}

	xsg_debug("get_stats_discarded_code: %f",
			(double) stats.discard.code);
	return (double) stats.discard.code;
}
Beispiel #2
0
static const char *
get_power_management(void *arg)
{
	static xsg_string_t *string = NULL;
	wrq.u.power.flags = 0;

	if (iw_get_ext(skfd, arg, SIOCGIWPOWER, &wrq) < 0) {
		xsg_debug("get_power_management: UNKNOWN");
		return NULL;
	}

	if (wrq.u.power.disabled) {
		xsg_debug("get_power_management: \"off\"");
		return "off";
	}

	if (string == NULL) {
		string = xsg_string_new(NULL);
	}

	if (wrq.u.power.flags & IW_POWER_TYPE) {
		if (iw_get_range_info(skfd, arg, &range) >= 0) {
			iw_print_pm_value(buffer, sizeof(buffer),
					wrq.u.power.value, wrq.u.power.flags,
					range.we_version_compiled);
			xsg_string_append_len(string, buffer, -1);
		}
	}

	iw_print_pm_mode(buffer, sizeof(buffer), wrq.u.power.flags);
	xsg_string_append_len(string, buffer, -1);

	if (wrq.u.power.flags == IW_POWER_ON) {
		xsg_string_append_len(string, "on", -1);
	}

	if (string->str[0] == ' ') {
		xsg_debug("get_power_management: \"%s\"", string->str + 1);
		return string->str + 1;
	} else {
		xsg_debug("get_power_management: \"%s\"", string->str);
		return string->str;
	}
}
Beispiel #3
0
/*
 * Display the channel (converted from frequency) if possible
 */
static int
print_channel(int		skfd,
	      const char *	ifname,
	      int		format)
{
  struct iwreq		wrq;
  struct iw_range	range;
  double		freq;
  int			channel;

  /* Get frequency / channel */
  if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
    return(-1);

  /* Convert to channel */
  if(iw_get_range_info(skfd, ifname, &range) < 0)
    return(-2);
  freq = iw_freq2float(&(wrq.u.freq));
  if(freq < KILO)
    channel = (int) freq;
  else
    {
      channel = iw_freq_to_channel(freq, &range);
      if(channel < 0)
	return(-3);
    }

  /* Print */
  switch(format)
    {
    case FORMAT_SCHEME:
      /* Prefix with freq to avoid name space collisions */
      printf("channel%d\n", channel);
      break;
    case FORMAT_RAW:
      printf("%d\n", channel);
      break;
    default:
      printf("%-8.16s  Channel:%d\n", ifname, channel);
      break;
    }

  return(0);
}
Beispiel #4
0
static double
get_stats_quality_noise(void *arg)
{
	int has_range = 1;

	if (iw_get_range_info(skfd, arg, &range) < 0) {
		has_range = 0;
	}

	if (iw_get_stats(skfd, arg, &stats, &range, has_range) < 0) {
		xsg_debug("get_stats_quality_noise: UNKNOWN");
		return DNAN;
	}

	if (has_range
	 && ((stats.qual.level != 0)
	  || (stats.qual.updated & (IW_QUAL_DBM | IW_QUAL_RCPI)))) {
		if (stats.qual.updated & IW_QUAL_RCPI) {
			if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
				xsg_debug("get_stats_quality_noise: %f",
					(stats.qual.noise / 2.0) - 110.0);
				return (stats.qual.noise / 2.0) - 110.0;
			}
		} else if ((stats.qual.updated & IW_QUAL_DBM)
			|| (stats.qual.level > range.max_qual.level)) {
			if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
				int dbnoise = stats.qual.noise;

				if (stats.qual.noise >= 64) {
					dbnoise -= 0x100;
				}

				xsg_debug("get_stats_quality_noise: %f",
						(double) dbnoise);
				return (double) dbnoise;
			}
		}
	}

	xsg_debug("get_stats_quality_noise: UNKNOWN");
	return DNAN;
}
Beispiel #5
0
static double
get_freq_number(void *arg)
{
	double freq;

	if (iw_get_ext(skfd, arg, SIOCGIWFREQ, &wrq) < 0) {
		xsg_debug("get_freq_number: UNKNOWN");
		return DNAN;
	}

	freq = iw_freq2float(&(wrq.u.freq));

	if (freq < KILO) {
		if (iw_get_range_info(skfd, arg, &range) >= 0) {
			iw_channel_to_freq((int) freq, &freq, &range);
		}
	}

	xsg_debug("get_freq_number: %f", freq);
	return freq;
}
Beispiel #6
0
static double
get_channel(void *arg)
{
	double freq;

	if (iw_get_ext(skfd, arg, SIOCGIWFREQ, &wrq) < 0) {
		xsg_debug("get_channel: UNKNOWN");
		return DNAN;
	}

	freq = iw_freq2float(&(wrq.u.freq));

	if (freq >= KILO) {
		if (iw_get_range_info(skfd, arg, &range) >= 0) {
			return (double) iw_freq_to_channel(freq, &range);
		}
	}

	xsg_debug("get_channel: %f", freq);
	return freq;
}
Beispiel #7
0
char *get_wifi(char *buf) {
	char devpath[35], state[5];

	sprintf(devpath, "/sys/class/net/%s/operstate", WIRELESS_D);
	infile = fopen(devpath, "r");

	fscanf(infile, "%s", state); fclose(infile);
	if(strcmp(state, "up") == 0) {
		if(iw_get_basic_config(skfd, WIRELESS_D, &(winfo->b)) > -1) {
			if(iw_get_stats(skfd, WIRELESS_D, &(winfo->stats), &winfo->range, winfo->has_range) >= 0)
				winfo->has_stats = 1;
			if(iw_get_range_info(skfd, WIRELESS_D, &(winfo->range)) >= 0)
				winfo->has_range = 1;
			if(winfo->b.has_essid && winfo->b.essid_on)
				sprintf(buf, WIFI_S, winfo->b.essid, (winfo->stats.qual.qual * 100) / winfo->range.max_qual.qual);
		}
	}
	else
		sprintf(buf, NO_CONN_S);
	return buf;
}
Beispiel #8
0
  /**
  * @brief Fills in basic information like the essid and the maximum signal quality
  */
  bool openDevice()
  {
    if ((wifi_skfd = iw_sockets_open()) < 0)
    {
      ROS_ERROR("socket error");
      return false;
    }

    if (iw_get_basic_config(wifi_skfd, wifi_dev, &(wifi_info->b)) < 0)
    {
      /* If no wireless name : no wireless extensions */
      /* But let's check if the interface exists at all */
      struct ifreq ifr;

      strncpy(ifr.ifr_name, wifi_dev, IFNAMSIZ);
      int ret = ioctl(wifi_skfd, SIOCGIFFLAGS, &ifr);
      if (ret < 0)
      {
        ROS_ERROR("device doesn't exist");
        return false;
      }
      else
      {
        ROS_ERROR("operation not supported");
        return false;
      }
    }

    wifi_sig.essid = wifi_info->b.essid;

    if (iw_get_range_info(wifi_skfd, wifi_dev, &(wifi_info->range)) >= 0)
      wifi_info->has_range = 1;

    wifi_sig.link_quality_max = wifi_info->range.max_qual.qual;

    return true;

  }
Beispiel #9
0
static double
get_stats_missed_beacon(void *arg)
{
	int has_range = 1;

	if (iw_get_range_info(skfd, arg, &range) < 0) {
		has_range = 0;
	}

	if (range.we_version_compiled <= 11) {
		xsg_debug("get_stats_missed_beacon: UNKNOWN");
		return DNAN;
	}

	if (iw_get_stats(skfd, arg, &stats, &range, has_range) < 0) {
		xsg_debug("get_stats_missed_beacon: UNKNOWN");
		return DNAN;
	}

	xsg_debug("get_stats_missed_beacon: %f",
			(double) stats.miss.beacon);
	return (double) stats.miss.beacon;
}
Beispiel #10
0
static double
get_stats_discarded_retries(void *arg)
{
	int has_range = 1;

	if (iw_get_range_info(skfd, arg, &range) < 0) {
		has_range = 0;
	}

	if (range.we_version_compiled <= 11) {
		xsg_debug("get_stats_discarded_retries: UNKNOWN");
		return DNAN;
	}

	if (iw_get_stats(skfd, arg, &stats, &range, has_range) < 0) {
		xsg_debug("get_stats_discarded_retries: UNKNOWN");
		return DNAN;
	}

	xsg_debug("get_stats_discarded_retries: %f",
			(double) stats.discard.retries);
	return (double) stats.discard.retries;
}
/* check stats, modify the state attribute */
static void
wireless_applet_read_device_state (WirelessApplet *applet)
{
	iwrange range;
	iwstats stats;
	gboolean has_range;
	
	/* ewwwww */
	char *enum_args[] = { (char *)applet };

	/* clear the device list */
	g_list_foreach (applet->devices, (GFunc)g_free, NULL);
	g_list_free (applet->devices);
	applet->devices = NULL;

	/* get the config */
	iw_get_basic_config (applet->skfd, applet->device, &applet->cfg);

	iw_enum_devices (applet->skfd,
			 wireless_applet_device_handler,
			 enum_args, 1);

	has_range = iw_get_range_info (applet->skfd, applet->device, &range) < 0 ? FALSE : TRUE;

	if (!iw_get_stats (applet->skfd, applet->device, &stats,
			  &range, has_range)) {
		wireless_applet_update_state (applet,
					      applet->device,
					      stats.qual.qual,
					      stats.qual.level,
					      stats.qual.noise);
	} else {
		wireless_applet_update_state (applet,
					      applet->device,
					      -1, -1, -1);
	}
}
Beispiel #12
0
static double
get_txpower_dbm(void *arg)
{
	if (iw_get_range_info(skfd, arg, &range) < 0) {
		xsg_debug("get_txpower_dbm: UNKNOWN");
		return DNAN;
	}

	if (range.we_version_compiled <= 9) {
		xsg_debug("get_txpower_dbm: UNKNOWN");
		return DNAN;
	}

	if (iw_get_ext(skfd, arg, SIOCGIWTXPOW, &wrq) < 0) {
		xsg_debug("get_txpower_dbm: UNKNOWN");
		return DNAN;
	}

	if (wrq.u.txpower.disabled) {
		xsg_debug("get_txpower_dbm: UNKNOWN");
		return DNAN;
	}

	if (wrq.u.txpower.flags & IW_TXPOW_RELATIVE) {
		xsg_debug("get_txpower_dbm: UNKNOWN");
		return DNAN;
	}

	if (wrq.u.txpower.flags & IW_TXPOW_MWATT) {
		xsg_debug("get_txpower_dbm: %f", (double) iw_mwatt2dbm(wrq.u.txpower.value));
		return (double) iw_mwatt2dbm(wrq.u.txpower.value);
	}

	xsg_debug("get_txpower_dbm: %f", (double) wrq.u.txpower.value);
	return (double) wrq.u.txpower.value;
}
Beispiel #13
0
/*
 * Print Power Management info for each device
 */
static int
print_pm_info(int		skfd,
	      char *		ifname,
	      char *		args[],		/* Command line args */
	      int		count)		/* Args count */
{
  struct iwreq		wrq;
  struct iw_range	range;
  char			buffer[128];

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Extract range info */
  if((iw_get_range_info(skfd, ifname, &range) < 0) ||
     (range.we_version_compiled < 10))
      fprintf(stderr, "%-8.16s  no power management information.\n\n",
		      ifname);
  else
    {
      printf("%-8.16s  ", ifname);

      /* Display modes availables */
      if(range.pm_capa & IW_POWER_MODE)
	{
	  printf("Supported modes :\n          ");
	  if(range.pm_capa & (IW_POWER_UNICAST_R | IW_POWER_MULTICAST_R))
	    printf("\t\to Receive all packets (unicast & multicast)\n          ");
	  if(range.pm_capa & IW_POWER_UNICAST_R)
	    printf("\t\to Receive Unicast only (discard multicast)\n          ");
	  if(range.pm_capa & IW_POWER_MULTICAST_R)
	    printf("\t\to Receive Multicast only (discard unicast)\n          ");
	  if(range.pm_capa & IW_POWER_FORCE_S)
	    printf("\t\to Force sending using Power Management\n          ");
	  if(range.pm_capa & IW_POWER_REPEATER)
	    printf("\t\to Repeat multicast\n          ");
	}
      /* Display min/max period availables */
      if(range.pmp_flags & IW_POWER_PERIOD)
	{
	  int	flags = (range.pmp_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
	  /* Display if auto or fixed */
	  if(range.pmp_flags & IW_POWER_MIN)
	    printf("Auto  period  ; ");
	  else
	    printf("Fixed period  ; ");
	  /* Print the range */
	  iw_print_pm_value(buffer, sizeof(buffer),
			    range.min_pmp, flags | IW_POWER_MIN);
	  printf("%s\n                          ", buffer);
	  iw_print_pm_value(buffer, sizeof(buffer),
			    range.max_pmp, flags | IW_POWER_MAX);
	  printf("%s\n          ", buffer);
	}
      /* Display min/max timeout availables */
      if(range.pmt_flags & IW_POWER_TIMEOUT)
	{
	  int	flags = (range.pmt_flags & ~(IW_POWER_MIN | IW_POWER_MAX));
	  /* Display if auto or fixed */
	  if(range.pmt_flags & IW_POWER_MIN)
	    printf("Auto  timeout ; ");
	  else
	    printf("Fixed timeout ; ");
	  /* Print the range */
	  iw_print_pm_value(buffer, sizeof(buffer),
			    range.min_pmt, flags | IW_POWER_MIN);
	  printf("%s\n                          ", buffer);
	  iw_print_pm_value(buffer, sizeof(buffer),
			    range.max_pmt, flags | IW_POWER_MAX);
	  printf("%s\n          ", buffer);
	}

      /* Get current Power Management settings */
      wrq.u.power.flags = 0;
      if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
	{
	  int	flags = wrq.u.power.flags;

	  /* Is it disabled ? */
	  if(wrq.u.power.disabled)
	    printf("Current mode:off\n          ");
	  else
	    {
	      int	pm_mask = 0;

	      /* Let's check the mode */
	      iw_print_pm_mode(buffer, sizeof(buffer), flags);
	      printf("Current %s", buffer);

	      /* Let's check if nothing (simply on) */
	      if((flags & IW_POWER_MODE) == IW_POWER_ON)
		printf("mode:on");
	      printf("\n                 ");

	      /* Let's check the value and its type */
	      if(wrq.u.power.flags & IW_POWER_TYPE)
		{
		  iw_print_pm_value(buffer, sizeof(buffer),
				    wrq.u.power.value, wrq.u.power.flags);
		  printf("%s", buffer);
		}

	      /* If we have been returned a MIN value, ask for the MAX */
	      if(flags & IW_POWER_MIN)
		pm_mask = IW_POWER_MAX;
	      /* If we have been returned a MAX value, ask for the MIN */
	      if(flags & IW_POWER_MAX)
		pm_mask = IW_POWER_MIN;
	      /* If we have something to ask for... */
	      if(pm_mask)
		get_pm_value(skfd, ifname, &wrq, pm_mask,
			     buffer, sizeof(buffer));

	      /* And if we have both a period and a timeout, ask the other */
	      pm_mask = (range.pm_capa & (~(wrq.u.power.flags) &
					  IW_POWER_TYPE));
	      if(pm_mask)
		{
		  int	base_mask = pm_mask;
		  flags = get_pm_value(skfd, ifname, &wrq, pm_mask,
				       buffer, sizeof(buffer));
		  pm_mask = 0;

		  /* If we have been returned a MIN value, ask for the MAX */
		  if(flags & IW_POWER_MIN)
		    pm_mask = IW_POWER_MAX | base_mask;
		  /* If we have been returned a MAX value, ask for the MIN */
		  if(flags & IW_POWER_MAX)
		    pm_mask = IW_POWER_MIN | base_mask;
		  /* If we have something to ask for... */
		  if(pm_mask)
		    get_pm_value(skfd, ifname, &wrq, pm_mask,
				 buffer, sizeof(buffer));
		}
	    }
	}
      printf("\n");
    }
  return(0);
}
Beispiel #14
0
/*
 * Print the number of available transmit powers for the device
 */
static int
print_txpower_info(int		skfd,
		   char *	ifname,
		   char *	args[],		/* Command line args */
		   int		count)		/* Args count */
{
  struct iwreq		wrq;
  struct iw_range	range;
  int			dbm;
  int			mwatt;
  int			k;

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Extract range info */
  if((iw_get_range_info(skfd, ifname, &range) < 0) ||
     (range.we_version_compiled < 10))
      fprintf(stderr, "%-8.16s  no transmit-power information.\n\n",
		      ifname);
  else
    {
      if((range.num_txpower <= 0) || (range.num_txpower > IW_MAX_TXPOWER))
	printf("%-8.16s  unknown transmit-power information.\n\n", ifname);
      else
	{
	  printf("%-8.16s  %d available transmit-powers :\n",
		 ifname, range.num_txpower);
	  /* Print them all */
	  for(k = 0; k < range.num_txpower; k++)
	    {
	      /* Check for relative values */
	      if(range.txpower_capa & IW_TXPOW_RELATIVE)
		{
		  printf("\t  %d (no units)\n", range.txpower[k]);
		}
	      else
		{
		  if(range.txpower_capa & IW_TXPOW_MWATT)
		    {
		      dbm = iw_mwatt2dbm(range.txpower[k]);
		      mwatt = range.txpower[k];
		    }
		  else
		    {
		      dbm = range.txpower[k];
		      mwatt = iw_dbm2mwatt(range.txpower[k]);
		    }
		  printf("\t  %d dBm  \t(%d mW)\n", dbm, mwatt);
		}
	    }
	}

      /* Get current Transmit Power */
      if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
	{
	  printf("          Current Tx-Power");
	  /* Disabled ? */
	  if(wrq.u.txpower.disabled)
	    printf(":off\n\n");
	  else
	    {
	      /* Fixed ? */
	      if(wrq.u.txpower.fixed)
		printf("=");
	      else
		printf(":");
	      /* Check for relative values */
	      if(wrq.u.txpower.flags & IW_TXPOW_RELATIVE)
		{
		  /* I just hate relative value, because they are
		   * driver specific, so not very meaningfull to apps.
		   * But, we have to support that, because
		   * this is the way hardware is... */
		  printf("\t  %d (no units)\n", wrq.u.txpower.value);
		}
	      else
		{
		  if(wrq.u.txpower.flags & IW_TXPOW_MWATT)
		    {
		      dbm = iw_mwatt2dbm(wrq.u.txpower.value);
		      mwatt = wrq.u.txpower.value;
		    }
		  else
		    {
		      dbm = wrq.u.txpower.value;
		      mwatt = iw_dbm2mwatt(wrq.u.txpower.value);
		    }
		  printf("%d dBm  \t(%d mW)\n\n", dbm, mwatt);
		}
	    }
	}
    }
  return(0);
}
Beispiel #15
0
//noise levels, returned by this functions, are invalid, don't use them
void CWextHW::readScanResults() {
	if (m_wextFd == -1) {
		return;
	}
	//Kill Timer:
	if (m_scTimerId != -1) {
		killTimer(m_scPollrate);
		m_scTimerId = -1;
	}
	else { //This is not a timer call; this should not happen
		qWarning() << tr("Warning, no timer present while trying to get scan results");
		return;
	}
	struct iwreq wrq;
	memset(&wrq,0,sizeof(struct iwreq));
	unsigned char * buffer = NULL;		/* Results */
	int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
	struct iw_range range;
	memset(&range,0,sizeof(struct iw_range));
	int has_range;
	QList<WextRawScan> res = QList<WextRawScan>();
	WextRawScan singleres;
	singleres.bssid = libnutcommon::MacAddress();
	singleres.group = GCI_UNDEFINED;
	singleres.pairwise = PCI_UNDEFINED;
	singleres.protocols = PROTO_UNDEFINED;
	singleres.keyManagement = KM_UNDEFINED;
	
	/* workaround */
	struct wireless_config wifiConfig;
	memset(&wifiConfig,0,sizeof(struct wireless_config));

	/* Get basic information */ 
	if(iw_get_basic_config(m_wextFd, m_ifname.toAscii().constData(), &wifiConfig) < 0) {
		/* If no wireless name : no wireless extensions */ 
		/* But let's check if the interface exists at all */ 
		struct ifreq ifr;
		memset(&ifr,0,sizeof(struct ifreq)); 
	
		strncpy(ifr.ifr_name, m_ifname.toAscii().data(), IFNAMSIZ); 
		if(ioctl(m_wextFd, SIOCGIFFLAGS, &ifr) < 0) 
			qWarning() << tr("(Wireless Extension) No device present");
		else
			qWarning() << tr("(Wireless Extension) Device not supported");
		return;
	}
	qDebug() << "Fetched basic config.";
	
	/* Get AP address */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWAP, &wrq) >= 0) {
		qDebug() << "Got AP";
	}
	
	/* Get bit rate */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWRATE, &wrq) >= 0) {
		qDebug() << "Got bit rate";
	}
	
	/* Get Power Management settings */
	wrq.u.power.flags = 0;
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWPOWER, &wrq) >= 0) {
		qDebug() << "Got power";
	}
	/* workaround */

	/* Get range stuff */
	/* Get range stuff */
	qDebug() << QString("Getting range stuff for %1").arg(m_ifname.toAscii().data());
	if (iw_get_range_info(m_wextFd, m_ifname.toAscii().data(), &range) >= 0) {
		has_range = 1;
		qDebug() << "Success readWirelessInfo getrange" << strerror(errno);
	}
	else { //This is VERY strange: we always get the "operation not permitted" error, although iw_get_range() worked
		qDebug() << QString("Error \"hasRange == 0\" (%1)").arg(strerror(errno));
	}
	singleres.hasRange = has_range;

	//If we get a timeout for more than 5 times, stop polling.
	if (errno == EAGAIN) {
		qDebug() << "Scan results not available yet";
		m_scTimeOutCount++;
		if (m_scTimeOutCount == 5) {
			return;
		}
		m_scTimerId = startTimer(m_scPollrate);
		return;
	}
	
	qDebug() << "Got range stuff";

	if (has_range) {
		singleres.maxquality.level = (quint8) range.max_qual.level;
		singleres.maxquality.qual = (quint8) range.max_qual.qual;
		singleres.maxquality.noise = (quint8) range.max_qual.noise;
		singleres.maxquality.updated = (quint8) range.max_qual.updated;
		qDebug() << "RANGE (scanresults): " << singleres.maxquality.level  << singleres.maxquality.qual << singleres.maxquality.noise << singleres.maxquality.updated;
	}
	else {
		singleres.maxquality.level = 0;
		singleres.maxquality.qual = 0;
		singleres.maxquality.noise = 0;
		singleres.maxquality.updated = 0;
		qWarning() << tr("Range information are not available");
	}

	unsigned char * newbuf;
	for (int i=0; i <= 16; i++) { //realloc (don't do this forever)
		//Allocate newbuffer 
		newbuf = (uchar*) realloc(buffer, buflen);
		if(newbuf == NULL) {
			if (buffer) {
				free(buffer);
				buffer = NULL;
			}
			qDebug() << "Allocating buffer for Wext failed";
			return;
		}
		buffer = newbuf;
		
		//Set Request variables:
		wrq.u.data.pointer = buffer;
		wrq.u.data.flags = 0;
		wrq.u.data.length = buflen;
		
		//Get the data:
		if (iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWSCAN, &wrq) < 0) {
			//Buffer is too small
			if((errno == E2BIG) && (range.we_version_compiled > 16)) {
				
				//check if driver gives any hints about scan length:
				if (wrq.u.data.length > buflen) {
					buflen = wrq.u.data.length;
				}
				else { //If not, double the length
					buflen *= 2;
				}
				//Start from the beginning:
				qDebug() << "Buffer was too small";
				continue;
			}
			//No range error occured or kernel has wireless extension < 16
			if (errno == EAGAIN) {
				qDebug() << "Scan results not available yet";
				m_scTimerId = startTimer(m_scPollrate);
				return;
			}
			
			//Bad error occured
			if (buffer) {
				free(buffer);
				buffer = NULL;
			}
			qWarning() << tr("(%1) Failed to read scan data : %2").arg(m_ifname, QString(strerror(errno)));
		}
		else { //Results are there
			break;
		}
	}

	//Now read the data:
	if (wrq.u.data.length) {

		struct iw_event iwe;
		memset(&iwe,0,sizeof(struct iw_event));
		struct stream_descr stream;
		memset(&stream,0,sizeof(struct stream_descr));
		int ret;
		
		//Init event stream
// 		char buffer2[128];
		libnutcommon::MacAddress tmpMac;
		iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
		do {
			/* Extract an event and parse it*/
			memset(&iwe,0,sizeof(struct iw_event)); //valgrind complains about it?
			ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
			if(ret > 0) {
				//Now parse our scan event:
				switch(iwe.cmd) {
					case SIOCGIWAP:
						//ap_addr has type socketaddr
						//Workaround for macaddress
// 						iw_saether_ntop(&(iwe.u.ap_addr), buffer2);
// 						tmpMac = libnutcommon::MacAddress(QString::fromAscii(buffer2,128));
						tmpMac = libnutcommon::MacAddress( (ether_addr*) iwe.u.ap_addr.sa_data);
						if (singleres.bssid.zero()) { //First bssid
							singleres.bssid = tmpMac;
							qDebug() << "Start parsing one network" << singleres.bssid.toString();
						}
						// if our last bssid is different from the actual one, then we have to append it to our scanlist
						if ( (singleres.bssid != tmpMac) )  {
							res.append(singleres);
							qDebug() << "End parsing one network" << singleres.bssid.toString();
							//reset singleres
							singleres.ssid = QString();
							singleres.bssid.clear();
							singleres.quality = WextRawSignal();
							singleres.freq = -1;
							singleres.group = GCI_UNDEFINED;
							singleres.pairwise = PCI_UNDEFINED;
							singleres.keyManagement = KM_UNDEFINED;
							singleres.protocols = PROTO_UNDEFINED;
							singleres.opmode = OPM_AUTO;
							singleres.bssid = tmpMac;
							qDebug() << "Start parsing one network" << singleres.bssid.toString();
						}
						qDebug() << "BSSID" << singleres.bssid.toString();
						break;
					case IWEVQUAL: //Quality event:
						qDebug() << "Quality" << singleres.bssid.toString();
						singleres.quality.qual = (quint8) iwe.u.qual.qual;
						singleres.quality.level = (quint8) iwe.u.qual.level;
						singleres.quality.noise = (quint8) iwe.u.qual.noise;
						singleres.quality.updated = (quint8) iwe.u.qual.updated;
						qDebug() << "STATS (scanresults): " << singleres.quality.level << singleres.quality.qual << singleres.quality.noise << singleres.quality.updated;
						break;
					case SIOCGIWFREQ:
						qDebug() << "Frequency" << singleres.bssid.toString();
						{
							double freq;
							freq = iw_freq2float(&(iwe.u.freq)); //Hopefully in hz
							if ( ( (freq/1e9) < 10.0 ) && ( (freq/1e9) > 0.0 ) ) {
								singleres.freq = (int) (freq/1e6);
								qDebug() << "Channel for" << singleres.ssid << "is " << freq << singleres.freq;
							}
							else {
								singleres.freq = -1;
							}
						}
						break;
					
					case SIOCGIWMODE:
						qDebug() << "Mode:" << singleres.bssid.toString();
						if(iwe.u.mode >= IW_NUM_OPER_MODE) {
							iwe.u.mode = IW_NUM_OPER_MODE;
						}
						singleres.opmode = (OPMODE) iwe.u.mode;
						break;
					case SIOCGIWESSID:
						qDebug() << "ESSID:" << singleres.bssid.toString();
						if (iwe.u.essid.flags) {
							/* Does it have an ESSID index ? */
							if ( iwe.u.essid.pointer && iwe.u.essid.length ) {
								if ( (iwe.u.essid.flags & IW_ENCODE_INDEX) > 1) {
									singleres.ssid = QString("%1 [%2]").arg(QString::fromAscii((char*) iwe.u.essid.pointer,iwe.u.essid.length), QString::number(iwe.u.essid.flags & IW_ENCODE_INDEX));
								}
								else {
									singleres.ssid = QString("%1").arg(QString::fromAscii((char*) iwe.u.essid.pointer,iwe.u.essid.length));
								}
							}
							else {
								singleres.ssid = QString("N/A");
							}
						}
						else { //Hidden essid or broken driver
							singleres.ssid = QString();
						}
						break;

					case SIOCGIWENCODE: //Get encrytion stuff: (just the key)
						qDebug() << "Encode" << singleres.bssid.toString();
						if (! iwe.u.data.pointer) {
							iwe.u.data.flags |= IW_ENCODE_NOKEY;
						}
						if(iwe.u.data.flags & IW_ENCODE_DISABLED) { //Encryption is disabled
							singleres.keyManagement = KM_NONE;
							qDebug() << "PARING ENCODE-Information: NO KEY";
						}
						else {
							//Extract key information: (See iwlib.c line 1500)
							
							//keyflags: iwe.u.data.flags
							//keysize = iwe.u.data.length
							//
							//Do we have a key
							if (iwe.u.data.flags & IW_ENCODE_NOKEY) { //no key
								if (iwe.u.data.length <= 0) {
									//Encryption is on, but group is unknown
									singleres.keyManagement = KM_NONE;
									qDebug() << "PARSING ENCODE-INFORMATION: WEP KEY";
								}
							} //else: we have a, key but check type later
						}
						break;

					case SIOCGIWRATE:
						singleres.bitrates.append((qint32) iwe.u.bitrate.value);
						qDebug() << "Adding Bitrate: " << (qint32) iwe.u.bitrate.value;
						break;
					
					case IWEVGENIE: //group/pairwsie ciphers etc.
						//buffer = iwe.u.data.pointer
						//bufflen = iwe.u.data.length
						qDebug() << "IE_START" << singleres.bssid.toString();
						{
							int offset = 0;
							/* Loop on each IE, each IE is minimum 2 bytes */
							while(offset <= (iwe.u.data.length - 2)) {
								/* Check IE type */
								if (0xdd == ((uchar *) iwe.u.data.pointer)[offset] || (0x30 == ((uchar *) iwe.u.data.pointer)[offset]) ) { // WPA1/2
									parseWextIeWpa(((uchar *) iwe.u.data.pointer) + offset, iwe.u.data.length, &singleres);

								qDebug() << "Parsed IE-Information of " << singleres.ssid << singleres.bssid.toString();
								qDebug() << toString(singleres.group) << toString(singleres.pairwise) << toString(singleres.keyManagement);
								}
								/* Skip over this IE to the next one in the list. */
								offset += buffer[offset+1] + 2;
							}
						}
						qDebug() << "IE_END" << singleres.bssid.toString();
						break;

					default: //Ignore all other event types. Maybe we need them later?
						break;
				}
			}
			else { //Append last scan:
				if (!singleres.bssid.zero()) {
					res.append(singleres);
					qDebug() << "End parsing one network" << singleres.bssid.toString();
				}
			}
	
		} while(ret > 0);

		//Delete buffer
		if (buffer) {
			free(buffer);
			buffer = NULL;
		}
		//We have the data, now construct complete ScanResult
		setScanResults(res);
	}
	else {
		qWarning() << tr("No Scanresults available");
		setScanResults(QList<WextRawScan>());
	}
	if (buffer) {
		free(buffer);
		buffer = NULL;
	}
}
Beispiel #16
0
/*
 * Set Power Management
 */
static int
set_power_info(int		skfd,
	       char *		ifname,
	       char *		args[],		/* Command line args */
	       int		count)		/* Args count */
{
  struct iwreq		wrq;
  int			i = 1;

  if(!strcasecmp(args[0], "off"))
    wrq.u.power.disabled = 1;	/* i.e. max size */
  else
    if(!strcasecmp(args[0], "on"))
      {
	/* Get old Power info */
	wrq.u.power.flags = 0;
	if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) < 0)
	  return(IWERR_GET_EXT);
	wrq.u.power.disabled = 0;
      }
    else
      {
	double		value;
	char *		unit;
	int		gotone = 0;

	/* Parse modifiers */
	i = parse_modifiers(args, count, &wrq.u.power.flags,
			    iwmod_power, IWMOD_POWER_NUM);
	if(i < 0)
	  return(i);

	wrq.u.power.disabled = 0;

	/* Is there any value to grab ? */
	value = strtod(args[0], &unit);
	if(unit != args[0])
	  {
	    struct iw_range	range;
	    int			flags;
	    /* Extract range info to handle properly 'relative' */
	    if(iw_get_range_info(skfd, ifname, &range) < 0)
	      memset(&range, 0, sizeof(range));

	    /* Get the flags to be able to do the proper conversion */
	    switch(wrq.u.power.flags & IW_POWER_TYPE)
	      {
	      case IW_POWER_SAVING:
		flags = range.pms_flags;
		break;
	      case IW_POWER_TIMEOUT:
		flags = range.pmt_flags;
		break;
	      default:
		flags = range.pmp_flags;
		break;
	      }
	    /* Check if time or relative */
	    if(flags & IW_POWER_RELATIVE)
	      {
		if(range.we_version_compiled < 21)
		  value *= MEGA;
		else
		  wrq.u.power.flags |= IW_POWER_RELATIVE;
	      }
	    else
	      {
		value *= MEGA;	/* default = s */
		if(unit[0] == 'u') value /= MEGA;
		if(unit[0] == 'm') value /= KILO;
	      }
	    wrq.u.power.value = (long) value;
	    /* Set some default type if none */
	    if((wrq.u.power.flags & IW_POWER_TYPE) == 0)
	      wrq.u.power.flags |= IW_POWER_PERIOD;
	    ++i;
	    gotone = 1;
	  }

	/* Now, check the mode */
	if(i < count)
	  {
	    if(!strcasecmp(args[i], "all"))
	      wrq.u.power.flags |= IW_POWER_ALL_R;
	    if(!strncasecmp(args[i], "unicast", 4))
	      wrq.u.power.flags |= IW_POWER_UNICAST_R;
	    if(!strncasecmp(args[i], "multicast", 5))
	      wrq.u.power.flags |= IW_POWER_MULTICAST_R;
	    if(!strncasecmp(args[i], "force", 5))
	      wrq.u.power.flags |= IW_POWER_FORCE_S;
	    if(!strcasecmp(args[i], "repeat"))
	      wrq.u.power.flags |= IW_POWER_REPEATER;
	    if(wrq.u.power.flags & IW_POWER_MODE)
	      {
		++i;
		gotone = 1;
	      }
	  }
	if(!gotone)
	  {
	    errarg = i;
	    return(IWERR_ARG_TYPE);
	  }
      }

  if(iw_set_ext(skfd, ifname, SIOCSIWPOWER, &wrq) < 0)
    return(IWERR_SET_EXT);

  /* Var args */
  return(i);
}
Beispiel #17
0
APLIST *wireless_scanning(int iwsockfd, const char *ifname)
{
	APLIST *ap = NULL;
	APLIST *newap;

	struct iwreq wrq;
	int scanflags = 0;		/* Flags for scan */
	unsigned char *	buffer = NULL;	/* Results */
	int buflen = IW_SCAN_MAX_DATA;	/* Min for compat WE < 17 */
	struct iw_range	range;
	int has_range;
	struct timeval tv;		/* select timeout */
	int timeout = 15000000;		/* 15s */

	/* Get range stuff */
	has_range = (iw_get_range_info(iwsockfd, ifname, &range) >= 0);

	/* Check if the interface could support scanning. */
	if ((!has_range) || (range.we_version_compiled < 14)) {
		fprintf(stderr, "%-8.16s  Interface doesn't support scanning.\n\n",
				ifname);
		return NULL;
	}

	/* Init timeout value -> 250ms between set and first get */
	tv.tv_sec = 0;
	tv.tv_usec = 250000;

	wrq.u.data.pointer = NULL;
	wrq.u.data.flags = 0;
	wrq.u.data.length = 0;

	/* Initiate Scanning */
	if (iw_set_ext(iwsockfd, ifname, SIOCSIWSCAN, &wrq) < 0) {
		if ((errno != EPERM) || (scanflags != 0)) {
			fprintf(stderr, "%-8.16s  Interface doesn't support "
				"scanning : %s\n\n", ifname, strerror(errno));
			return NULL;
		}
		tv.tv_usec = 0;
	}
	timeout -= tv.tv_usec;

	/* Forever */
	while (1) {
		fd_set rfds;		/* File descriptors for select */
		int last_fd;	/* Last fd */
		int ret;

		/* Guess what ? We must re-generate rfds each time */
		FD_ZERO(&rfds);
		last_fd = -1;

		/* In here, add the rtnetlink fd in the list */

		/* Wait until something happens */
		ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);

		/* Check if there was an error */
		if (ret < 0) {
			if (errno == EAGAIN || errno == EINTR)
				continue;
			fprintf(stderr, "Unhandled signal - exiting...\n");
			return NULL;
		}

		/* Check if there was a timeout */
		if (ret == 0) {
			unsigned char *newbuf;

realloc:
			/* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
			newbuf = realloc(buffer, buflen);
			if (newbuf == NULL) {
				if (buffer)
					free(buffer);
				fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
				return NULL;
			}
			buffer = newbuf;

			/* Try to read the results */
			wrq.u.data.pointer = buffer;
			wrq.u.data.flags = 0;
			wrq.u.data.length = buflen;
			if (iw_get_ext(iwsockfd, ifname, SIOCGIWSCAN, &wrq) < 0)	{
				/* Check if buffer was too small (WE-17 only) */
				if ((errno == E2BIG) &&
				    (range.we_version_compiled > 16)) {
					/* Check if the driver gave us any hints. */
					if (wrq.u.data.length > buflen)
						buflen = wrq.u.data.length;
					else
						buflen *= 2;
					/* Try again */
					goto realloc;
				}

				/* Check if results not available yet */
				if(errno == EAGAIN) {
					/* Restart timer for only 100ms*/
					tv.tv_sec = 0;
					tv.tv_usec = 100000;
					timeout -= tv.tv_usec;
					if (timeout > 0)
						continue; /* Try again later */
				}

				/* Bad error */
				free(buffer);
				fprintf(stderr,
				"%-8.16s  Failed to read scan data : %s\n\n",
						ifname, strerror(errno));
				return NULL;
			}
			else
				/* We have the results, go to process them */
				break;
		}

		/* In here, check if event and event type
		 * if scan event, read results. All errors bad & no reset timeout */
	}

	if(wrq.u.data.length) {
		struct iw_event           iwe;
		struct stream_descr       stream;
		int                       ret;

		iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
		do {
			/* Extract an event and print it */
			ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
			if (iwe.cmd==SIOCGIWAP) {
				newap = malloc(sizeof(APLIST));
				newap->info = NULL;
				newap->next = ap;
				ap = newap;
			}
			ap->info = wireless_parse_scanning_event(&iwe, ap->info);
		}
		while (ret > 0);
		printf("\n");
	}
	else
		printf("%-8.16s  No scan results\n\n", ifname);

	free(buffer);
	return ap;
}
Beispiel #18
0
/*
 * Set Retry Limit
 */
static int
set_retry_info(int		skfd,
	       char *		ifname,
	       char *		args[],		/* Command line args */
	       int		count)		/* Args count */
{
  struct iwreq		wrq;
  int			i = 0;
  double		value;
  char *		unit;

  /* Parse modifiers */
  i = parse_modifiers(args, count, &wrq.u.retry.flags,
		      iwmod_retry, IWMOD_RETRY_NUM);
  if(i < 0)
    return(i);

  /* Add default type if none */
  if((wrq.u.retry.flags & IW_RETRY_TYPE) == 0)
    wrq.u.retry.flags |= IW_RETRY_LIMIT;

  wrq.u.retry.disabled = 0;

  /* Is there any value to grab ? */
  value = strtod(args[0], &unit);
  if(unit == args[0])
    {
      errarg = i;
      return(IWERR_ARG_TYPE);
    }

  /* Limit is absolute, on the other hand lifetime is seconds */
  if(wrq.u.retry.flags & IW_RETRY_LIFETIME)
    {
      struct iw_range	range;
      /* Extract range info to handle properly 'relative' */
      if(iw_get_range_info(skfd, ifname, &range) < 0)
	memset(&range, 0, sizeof(range));

      if(range.r_time_flags & IW_RETRY_RELATIVE)
	{
	  if(range.we_version_compiled < 21)
	    value *= MEGA;
	  else
	    wrq.u.retry.flags |= IW_RETRY_RELATIVE;
	}
      else
	{
	  /* Normalise lifetime */
	  value *= MEGA;	/* default = s */
	  if(unit[0] == 'u') value /= MEGA;
	  if(unit[0] == 'm') value /= KILO;
	}
    }
  wrq.u.retry.value = (long) value;
  ++i;

  if(iw_set_ext(skfd, ifname, SIOCSIWRETRY, &wrq) < 0)
    return(IWERR_SET_EXT);

  /* Var args */
  return(i);
}
Beispiel #19
0
/*
 * Display the spy list of addresses and the associated stats
 */
static int
print_spy_info(int	skfd,
	       char *	ifname,
	       char *	args[],
	       int	count)
{
  struct iwreq		wrq;
  char		buffer[(sizeof(struct iw_quality) +
			sizeof(struct sockaddr)) * IW_MAX_SPY];
  char		temp[128];
  struct sockaddr *	hwa;
  struct iw_quality *	qual;
  iwrange	range;
  int		has_range = 0;
  int		n;
  int		i;

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Collect stats */
  wrq.u.data.pointer = (caddr_t) buffer;
  wrq.u.data.length = IW_MAX_SPY;
  wrq.u.data.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
    {
      fprintf(stderr, "%-8.16s  Interface doesn't support wireless statistic collection\n\n", ifname);
      return(-1);
    }

  /* Number of addresses */
  n = wrq.u.data.length;

  /* Check if we have valid mac address type */
  if(iw_check_mac_addr_type(skfd, ifname) < 0)
    {
      fprintf(stderr, "%-8.16s  Interface doesn't support MAC addresses\n\n", ifname);
      return(-2);
    }

  /* Get range info if we can */
  if(iw_get_range_info(skfd, ifname, &(range)) >= 0)
    has_range = 1;

  /* Display it */
  if(n == 0)
    printf("%-8.16s  No statistics to collect\n", ifname);
  else
    printf("%-8.16s  Statistics collected:\n", ifname);
 
  /* The two lists */
  hwa = (struct sockaddr *) buffer;
  qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * n));

  for(i = 0; i < n; i++)
    {
      /* Print stats for each address */
      printf("    %s : ", iw_saether_ntop(&hwa[i], temp));
      iw_print_stats(temp, sizeof(temp), &qual[i], &range, has_range);
      printf("%s\n", temp);
    }

  if((n > 0) && (has_range) && (range.we_version_compiled > 11))
    {
      iwstats	stats;

      /* Get /proc/net/wireless */
      if(iw_get_stats(skfd, ifname, &stats, &range, has_range) >= 0)
	{
	  iw_print_stats(temp, sizeof(temp), &stats.qual, &range, has_range);
	  printf("    Link/Cell/AP      : %s\n", temp);
	  /* Display the static data */
	  iw_print_stats(temp, sizeof(temp),
			 &range.avg_qual, &range, has_range);
	  printf("    Typical/Reference : %s\n", temp);
	}
    }

  printf("\n");
  return(0);
}
Beispiel #20
0
static int get_wireless_info(const char *interface, wireless_info_t *info) {
        memset(info, 0, sizeof(wireless_info_t));

#ifdef LINUX
        int skfd = iw_sockets_open();
        if (skfd < 0) {
                perror("iw_sockets_open");
                return 0;
        }

        wireless_config wcfg;
        if (iw_get_basic_config(skfd, interface, &wcfg) < 0) {
            close(skfd);
            return 0;
        }

        if (wcfg.has_essid && wcfg.essid_on) {
                info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
                strncpy(&info->essid[0], wcfg.essid, IW_ESSID_MAX_SIZE);
                info->essid[IW_ESSID_MAX_SIZE] = '\0';
        }

        /* If the function iw_get_stats does not return proper stats, the
           wifi is considered as down.
           Since ad-hoc network does not have theses stats, we need to return
           here for this mode. */
        if (wcfg.mode == 1) {
                close(skfd);
                return 1;
        }

        /* Wireless quality is a relative value in a driver-specific range.
           Signal and noise level can be either relative or absolute values
           in dBm. Furthermore, noise and quality can be expressed directly
           in dBm or in RCPI (802.11k), which we convert to dBm. When those
           values are expressed directly in dBm, they range from -192 to 63,
           and since the values are packed into 8 bits, we need to perform
           8-bit arithmetic on them. Assume absolute values if everything
           else fails (driver bug). */

        iwrange range;
        if (iw_get_range_info(skfd, interface, &range) < 0) {
                close(skfd);
                return 0;
        }

        iwstats stats;
        if (iw_get_stats(skfd, interface, &stats, &range, 1) < 0) {
                close(skfd);
                return 0;
        }

        if (stats.qual.level != 0 || (stats.qual.updated & (IW_QUAL_DBM | IW_QUAL_RCPI))) {
                if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
                        info->quality = stats.qual.qual;
                        info->quality_max = range.max_qual.qual;
                        info->quality_average = range.avg_qual.qual;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
                }

                if (stats.qual.updated & IW_QUAL_RCPI) {
                        if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                                info->signal_level = stats.qual.level / 2.0 - 110 + 0.5;
                                info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                        }
                        if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                                info->noise_level = stats.qual.noise / 2.0 - 110 + 0.5;
                                info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                        }
                }
                else {
                        if ((stats.qual.updated & IW_QUAL_DBM) || stats.qual.level > range.max_qual.level) {
                                if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                                        info->signal_level = stats.qual.level;
                                        if (info->signal_level > 63)
                                                info->signal_level -= 256;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                                }
                                if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                                        info->noise_level = stats.qual.noise;
                                        if (info->noise_level > 63)
                                                info->noise_level -= 256;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                                }
                        }
                        else {
                                if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                                        info->signal_level = stats.qual.level;
                                        info->signal_level_max = range.max_qual.level;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                                }
                                if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                                        info->noise_level = stats.qual.noise;
                                        info->noise_level_max = range.max_qual.noise;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                                }
                        }
                }
        }
        else {
                if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
                        info->quality = stats.qual.qual;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
                }
                if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                        info->quality = stats.qual.level;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                }
                if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                        info->quality = stats.qual.noise;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                }
        }

        struct iwreq wrq;
        if (iw_get_ext(skfd, interface, SIOCGIWRATE, &wrq) >= 0)
                info->bitrate = wrq.u.bitrate.value;

        close(skfd);
        return 1;
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
        int s, len, inwid;
        uint8_t buf[24 * 1024], *cp;
        struct ieee80211req na;
        char network_id[IEEE80211_NWID_LEN + 1];

        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
                return (0);

        memset(&na, 0, sizeof(na));
        strlcpy(na.i_name, interface, sizeof(na.i_name));
        na.i_type = IEEE80211_IOC_SSID;
        na.i_data = &info->essid[0];
        na.i_len = IEEE80211_NWID_LEN + 1;
        if ((inwid = ioctl(s, SIOCG80211, (caddr_t)&na)) == -1) {
                close(s);
                return (0);
        }
        if (inwid == 0) {
                if (na.i_len <= IEEE80211_NWID_LEN)
                        len = na.i_len + 1;
                else
                        len = IEEE80211_NWID_LEN + 1;
                info->essid[len -1] = '\0';
        } else {
                close(s);
                return (0);
        }
        info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;

        memset(&na, 0, sizeof(na));
        strlcpy(na.i_name, interface, sizeof(na.i_name));
        na.i_type = IEEE80211_IOC_SCAN_RESULTS;
        na.i_data = buf;
        na.i_len = sizeof(buf);

        if (ioctl(s, SIOCG80211, (caddr_t)&na) == -1) {
                printf("fail\n");
                close(s);
                return (0);
        }

        close(s);
        len = na.i_len;
        cp = buf;
        struct ieee80211req_scan_result *sr;
        uint8_t *vp;
        sr = (struct ieee80211req_scan_result *)cp;
        vp = (u_int8_t *)(sr + 1);
        strlcpy(network_id, (const char *)vp, sr->isr_ssid_len + 1);
        if (!strcmp(network_id, &info->essid[0])) {
                info->signal_level = sr->isr_rssi;
                info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                info->noise_level = sr->isr_noise;
                info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                info->quality = sr->isr_intval;
                info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
        }

        return 1;
#endif
#ifdef __OpenBSD__
	struct ifreq ifr;
	struct ieee80211_bssid bssid;
	struct ieee80211_nwid nwid;
	struct ieee80211_nodereq nr;

	struct ether_addr ea;

        int s, len, ibssid, inwid;
	u_int8_t zero_bssid[IEEE80211_ADDR_LEN];

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		return (0);

        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_data = (caddr_t)&nwid;
	(void)strlcpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
        inwid = ioctl(s, SIOCG80211NWID, (caddr_t)&ifr);

	memset(&bssid, 0, sizeof(bssid));
	strlcpy(bssid.i_name, interface, sizeof(bssid.i_name));
	ibssid = ioctl(s, SIOCG80211BSSID, &bssid);

	if (ibssid != 0 || inwid != 0) {
		close(s);
		return 0;
	}

	/* NWID */
	{
		if (nwid.i_len <= IEEE80211_NWID_LEN)
			len = nwid.i_len + 1;
		else
			len = IEEE80211_NWID_LEN + 1;

		strncpy(&info->essid[0], nwid.i_nwid, len);
		info->essid[IW_ESSID_MAX_SIZE] = '\0';
		info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
	}

	/* Signal strength */
	{
		memset(&zero_bssid, 0, sizeof(zero_bssid));
		if (ibssid == 0 && memcmp(bssid.i_bssid, zero_bssid, IEEE80211_ADDR_LEN) != 0) {
			memcpy(&ea.ether_addr_octet, bssid.i_bssid, sizeof(ea.ether_addr_octet));

			bzero(&nr, sizeof(nr));
			bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr));
			strlcpy(nr.nr_ifname, interface, sizeof(nr.nr_ifname));

			if (ioctl(s, SIOCG80211NODE, &nr) == 0 && nr.nr_rssi) {
				if (nr.nr_max_rssi)
					info->signal_level_max = IEEE80211_NODEREQ_RSSI(&nr);
				else
					info->signal_level = nr.nr_rssi;

		                info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
			}
		}
	}

	close(s);
	return 1;
#endif
	return 0;
}
Beispiel #21
0
/* ---------------------------------------------------------------------- WirelessInterface_Scan */
static PyObject* WirelessInterface_Scan(wiface* self)
{
	iwreq wrq;
	unsigned char* buffer = NULL;
	int buflen            = IW_SCAN_MAX_DATA;
	iwrange range;
	int has_range;
	timeval tv;
	int timeout           = 15000000;
	PyObject* scan_list   = NULL;

	has_range = (iw_get_range_info(self->sock, self->ifname, &range) >= 0);

	tv.tv_sec          = 0;
	tv.tv_usec         = 250000;
	wrq.u.data.pointer = NULL;
	wrq.u.data.flags   = 0;
	wrq.u.data.length  = 0;

	if (iw_set_ext(self->sock, self->ifname, SIOCSIWSCAN, &wrq) < 0) {
		if (errno != EPERM) {
			PyErr_SetString(IwScanError, "Interface doesn't support scanning");
			return NULL;
		}

		tv.tv_usec = 0;
	}

	timeout -= tv.tv_usec;

	while (1) {
		fd_set rfds;
		int last_fd;
		int ret;

		FD_ZERO(&rfds);
		last_fd = -1;

		ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);

		if (ret < 0) {
			if (errno == EAGAIN || errno == EINTR)
				continue;
			else {
				PyErr_SetString(IwScanError, "Unknown scanning error");
				return NULL;
			}
		}

		if (!ret) {
			unsigned char* newbuf;

 realloc:
			newbuf = realloc(buffer, buflen);

			if (!newbuf) {
				if (buffer)
					free(buffer);

				PyErr_SetString(IwScanError, "Memory allocation failure in scan");
				return NULL;
			}

			buffer = newbuf;

			wrq.u.data.pointer = buffer;
			wrq.u.data.flags   = 0;
			wrq.u.data.length  = buflen;

			if (iw_get_ext(self->sock, self->ifname, SIOCGIWSCAN, &wrq) < 0) {
				if ((errno == E2BIG)) {
					if (wrq.u.data.length > buflen)
						buflen = wrq.u.data.length;
					else
						buflen *= 2;

					goto realloc;
				}

				if (errno == EAGAIN) {
					tv.tv_sec   = 0;
					tv.tv_usec  = 100000;
					timeout    -= tv.tv_usec;

					if (timeout > 0)
						continue;
				}

				free(buffer);

				PyErr_SetString(IwScanError, "Unable to read scan data");
				return NULL;
			}
			else
				break;
		}
	}

	if (wrq.u.data.length) {
		iwevent iwe;
		stream_descr stream;
		int ret;
		PyObject* scan_dict = NULL;

		scan_list = PyList_New(0);

		iw_init_event_stream(&stream, (char*)(buffer), wrq.u.data.length);

		do {
			ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);

			if (ret > 0) {
				wifacesd sd;
				int sr = WirelessInterface_ScanItem(&sd, &iwe, &range, has_range);

				if (sr) {
					int i;

					if (scan_dict) {
						PyList_Append(scan_list, scan_dict);
						Py_DECREF(scan_dict);
					}

					scan_dict = PyDict_New();

					for (i = 0; i < IWSCAN_INTERFACE_KEYS; i++) {
						PyMapping_SetItemString(scan_dict,
									WirelessInterfaceKeys[i],
									Py_BuildValue(""));
					}
				}

				if (sd.num) {
					int i;

					for (i = 0; i < sd.num; i++) {
						PyMapping_SetItemString(scan_dict,
									WirelessInterfaceKeys[sd.keys[i]],
									sd.objs[i]);

						Py_DECREF(sd.objs[i]);
					}
				}
			}
		} while (ret > 0);

		PyList_Append(scan_list, scan_dict);
		Py_XDECREF(scan_dict);
	}
	else
		return Py_BuildValue("[]");

	free(buffer);

	return scan_list;
}
Beispiel #22
0
/*
 * Get wireless informations & config from the device driver
 * We will call all the classical wireless ioctl on the driver through
 * the socket to know what is supported and to get the settings...
 */
static int
get_info(int			skfd,
	 char *			ifname,
	 struct wireless_info *	info)
{
  struct iwreq		wrq;

  memset((char *) info, 0, sizeof(struct wireless_info));

  /* Get wireless name */
  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
    {
      /* If no wireless name : no wireless extensions */
      /* But let's check if the interface exists at all */
      struct ifreq ifr;

	  // cefiro 2004/1/12 14:39
	  printf("ifname     = %s\n", ifname);
	  printf("skfd       = %d\n", skfd);
	  printf("SIOCGIWNAME= %d\n", SIOCGIWNAME);

      strcpy(ifr.ifr_name, ifname);
      if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
	return(-ENODEV);
      else
	return(-ENOTSUP);
    }
  else
    {
      strncpy(info->name, wrq.u.name, IFNAMSIZ);
      info->name[IFNAMSIZ] = '\0';
    }

  /* Get ranges */
  if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
    info->has_range = 1;

  /* Get network ID */
  if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) >= 0)
    {
      info->has_nwid = 1;
      memcpy(&(info->nwid), &(wrq.u.nwid), sizeof(iwparam));
    }

  /* Get frequency / channel */
  if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
    {
      info->has_freq = 1;
      info->freq = iw_freq2float(&(wrq.u.freq));
    }

  /* Get sensitivity */
  if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
    {
      info->has_sens = 1;
      memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
    }

  /* Get encryption information */
  wrq.u.data.pointer = (caddr_t) info->key;
  wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
  wrq.u.data.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
    {
      info->has_key = 1;
      info->key_size = wrq.u.data.length;
      info->key_flags = wrq.u.data.flags;
    }

  /* Get ESSID */
  wrq.u.essid.pointer = (caddr_t) info->essid;
  wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
  wrq.u.essid.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) >= 0)
    {
      info->has_essid = 1;
      info->essid_on = wrq.u.data.flags;
    }

  /* Get AP address */
  if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
    {
      info->has_ap_addr = 1;
      memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
    }

  /* Get NickName */
  wrq.u.essid.pointer = (caddr_t) info->nickname;
  wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
  wrq.u.essid.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
    if(wrq.u.data.length > 1)
      info->has_nickname = 1;

  /* Get bit rate */
  if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
    {
      info->has_bitrate = 1;
      memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
    }

  /* Get RTS threshold */
  if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
    {
      info->has_rts = 1;
      memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
    }

  /* Get fragmentation threshold */
  if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
    {
      info->has_frag = 1;
      memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
    }

  /* Get operation mode */
  if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
    {
      info->mode = wrq.u.mode;
      if((info->mode < IW_NUM_OPER_MODE) && (info->mode >= 0))
	info->has_mode = 1;
    }

  /* Get Power Management settings */
  wrq.u.power.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
    {
      info->has_power = 1;
      memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
    }

#if WIRELESS_EXT > 9
  /* Get Transmit Power */
  if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
    {
      info->has_txpower = 1;
      memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
    }
#endif

#if WIRELESS_EXT > 10
  /* Get retry limit/lifetime */
  if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
    {
      info->has_retry = 1;
      memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
    }
#endif	/* WIRELESS_EXT > 10 */

  /* Get stats */
  if(iw_get_stats(skfd, ifname, &(info->stats)) >= 0)
    {
      info->has_stats = 1;
    }

  return(0);
}
Beispiel #23
0
/*
 * Set the wireless options requested on command line
 * This function is too long and probably should be split,
 * because it look like the perfect definition of spaghetti code,
 * but I'm way to lazy
 */
static int
set_info(int		skfd,		/* The socket */
	 char *		args[],		/* Command line args */
	 int		count,		/* Args count */
	 char *		ifname)		/* Dev name */
{
  struct iwreq		wrq;
  int			i;

  /* if nothing after the device name - will never happen */
  if(count < 1)
    {
      fprintf(stderr, "Error : too few arguments.\n");
      return(-1);
    }

  /* The other args on the line specify options to be set... */
  for(i = 0; i < count; i++)
    {
      /* ---------- Commit changes to driver ---------- */
      if(!strncmp(args[i], "commit", 6))
	{
	  /* No args */
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWCOMMIT, &wrq,
			 "Commit changes");
	  continue;
	}

      /* ---------- Set network ID ---------- */
      if((!strcasecmp(args[i], "nwid")) ||
	 (!strcasecmp(args[i], "domain")))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set NWID", SIOCSIWNWID);
	  if((!strcasecmp(args[i], "off")) ||
	     (!strcasecmp(args[i], "any")))
	    wrq.u.nwid.disabled = 1;
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old nwid */
		IW_GET_EXT_ERR(skfd, ifname, SIOCGIWNWID, &wrq,
			       "Set NWID");
		wrq.u.nwid.disabled = 0;
	      }
	    else
	      if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
		 != 1)
		ABORT_ARG_TYPE("Set NWID", SIOCSIWNWID, args[i]);
	      else
		wrq.u.nwid.disabled = 0;
	  wrq.u.nwid.fixed = 1;

	  /* Set new nwid */
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNWID, &wrq,
			 "Set NWID");
	  continue;
	}

      /* ---------- Set frequency / channel ---------- */
      if((!strncmp(args[i], "freq", 4)) ||
	 (!strcmp(args[i], "channel")))
	{
	  double		freq;

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Frequency", SIOCSIWFREQ);
	  if(sscanf(args[i], "%lg", &(freq)) != 1)
	    ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
	  if(index(args[i], 'G')) freq *= GIGA;
	  if(index(args[i], 'M')) freq *= MEGA;
	  if(index(args[i], 'k')) freq *= KILO;

	  iw_float2freq(freq, &(wrq.u.freq));

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq,
			 "Set Frequency");
	  continue;
	}

      /* ---------- Set sensitivity ---------- */
      if(!strncmp(args[i], "sens", 4))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set Sensitivity", SIOCSIWSENS);
	  if(sscanf(args[i], "%i", &(wrq.u.sens.value)) != 1)
	    ABORT_ARG_TYPE("Set Sensitivity", SIOCSIWSENS, args[i]);

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWSENS, &wrq,
			 "Set Sensitivity");
	  continue;
	}

      /* ---------- Set encryption stuff ---------- */
      if((!strncmp(args[i], "enc", 3)) ||
	 (!strcmp(args[i], "key")))
	{
	  unsigned char	key[IW_ENCODING_TOKEN_MAX];

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Encode", SIOCSIWENCODE);

	  if(!strcasecmp(args[i], "on"))
	    {
	      /* Get old encryption information */
	      wrq.u.data.pointer = (caddr_t) key;
	      wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
	      wrq.u.data.flags = 0;
	      IW_GET_EXT_ERR(skfd, ifname, SIOCGIWENCODE, &wrq,
			     "Set Encode");
	      wrq.u.data.flags &= ~IW_ENCODE_DISABLED;	/* Enable */
	    }
	  else
	    {
	      int	gotone = 0;
	      int	oldone;
	      int	keylen;
	      int	temp;

	      wrq.u.data.pointer = (caddr_t) NULL;
	      wrq.u.data.flags = 0;
	      wrq.u.data.length = 0;

	      /* Allow arguments in any order (it's safe) */
	      do
		{
		  oldone = gotone;

		  /* -- Check for the key -- */
		  if(i < count)
		    {
		      keylen = iw_in_key_full(skfd, ifname,
					      args[i], key, &wrq.u.data.flags);
		      if(keylen > 0)
			{
			  wrq.u.data.length = keylen;
			  wrq.u.data.pointer = (caddr_t) key;
			  ++i;
			  gotone++;
			}
		    }

		  /* -- Check for token index -- */
		  if((i < count) &&
		     (sscanf(args[i], "%i", &temp) == 1) &&
		     (temp > 0) && (temp < IW_ENCODE_INDEX))
		    {
		      wrq.u.encoding.flags |= temp;
		      ++i;
		      gotone++;
		    }

		  /* -- Check the various flags -- */
		  if((i < count) && (!strcasecmp(args[i], "off")))
		    {
		      wrq.u.data.flags |= IW_ENCODE_DISABLED;
		      ++i;
		      gotone++;
		    }
		  if((i < count) && (!strcasecmp(args[i], "open")))
		    {
		      wrq.u.data.flags |= IW_ENCODE_OPEN;
		      ++i;
		      gotone++;
		    }
		  if((i < count) && (!strncasecmp(args[i], "restricted", 5)))
		    {
		      wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
		      ++i;
		      gotone++;
		    }
#if WIRELESS_EXT > 15
		  if((i < count) && (!strncasecmp(args[i], "temporary", 4)))
		    {
		      wrq.u.data.flags |= IW_ENCODE_TEMP;
		      ++i;
		      gotone++;
		    }
#endif
		}
	      while(gotone != oldone);

	      /* Pointer is absent in new API */
	      if(wrq.u.data.pointer == NULL)
		wrq.u.data.flags |= IW_ENCODE_NOKEY;

	      /* Check if we have any invalid argument */
	      if(!gotone)
		ABORT_ARG_TYPE("Set Encode", SIOCSIWENCODE, args[i]);
	      /* Get back to last processed argument */
	      --i;
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq,
			 "Set Encode");
	  continue;
  	}

      /* ---------- Set ESSID ---------- */
      if(!strcasecmp(args[i], "essid"))
	{
	  char		essid[IW_ESSID_MAX_SIZE + 1];

	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
	  if((!strcasecmp(args[i], "off")) ||
	     (!strcasecmp(args[i], "any")))
	    {
	      wrq.u.essid.flags = 0;
	      essid[0] = '\0';
	    }
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old essid */
		wrq.u.essid.pointer = (caddr_t) essid;
		wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
		wrq.u.essid.flags = 0;
		IW_GET_EXT_ERR(skfd, ifname, SIOCGIWESSID, &wrq,
			       "Set ESSID");
		wrq.u.essid.flags = 1;
	      }
	    else
	      {
		/* '-' allow to escape the ESSID string, allowing
		 * to set it to the string "any" or "off".
		 * This is a big ugly, but it will do for now */
		if(!strcmp(args[i], "-"))
		  {
		    i++;
		    if(i >= count)
		      ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
		  }

		/* Check the size of what the user passed us to avoid
		 * buffer overflows */
		if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
		  ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
		else
		  {
		    int		temp;

		    wrq.u.essid.flags = 1;
		    strcpy(essid, args[i]);	/* Size checked, all clear */

		    /* Check for ESSID index */
		    if(((i+1) < count) &&
		       (sscanf(args[i+1], "[%i]", &temp) == 1) &&
		       (temp > 0) && (temp < IW_ENCODE_INDEX))
		      {
			wrq.u.essid.flags = temp;
			++i;
		      }
		  }
	      }

	  wrq.u.essid.pointer = (caddr_t) essid;
	  wrq.u.essid.length = strlen(essid) + 1;
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq,
			 "Set ESSID");
	  continue;
	}

      /* ---------- Set AP address ---------- */
      if(!strcasecmp(args[i], "ap"))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set AP Address", SIOCSIWAP);

	  if((!strcasecmp(args[i], "auto")) ||
	     (!strcasecmp(args[i], "any")))
	    {
	      /* Send a broadcast address */
	      iw_broad_ether(&(wrq.u.ap_addr));
	    }
	  else
	    {
	      if(!strcasecmp(args[i], "off"))
		{
		  /* Send a NULL address */
		  iw_null_ether(&(wrq.u.ap_addr));
		}
	      else
		{
		  /* Get the address and check if the interface supports it */
		  if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
		    ABORT_ARG_TYPE("Set AP Address", SIOCSIWAP, args[i-1]);
		}
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWAP, &wrq,
			 "Set AP Address");
	  continue;
	}

      /* ---------- Set NickName ---------- */
      if(!strncmp(args[i], "nick", 4))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set Nickname", SIOCSIWNICKN);
	  if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
	    ABORT_ARG_SIZE("Set Nickname", SIOCSIWNICKN, IW_ESSID_MAX_SIZE);

	  wrq.u.essid.pointer = (caddr_t) args[i];
	  wrq.u.essid.length = strlen(args[i]) + 1;
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNICKN, &wrq,
			 "Set Nickname");
	  continue;
	}

      /* ---------- Set Bit-Rate ---------- */
      if((!strncmp(args[i], "bit", 3)) ||
	 (!strcmp(args[i], "rate")))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set Bit Rate", SIOCSIWRATE);
	  if(!strcasecmp(args[i], "auto"))
	    {
	      wrq.u.bitrate.value = -1;
	      wrq.u.bitrate.fixed = 0;
	    }
	  else
	    {
	      if(!strcasecmp(args[i], "fixed"))
		{
		  /* Get old bitrate */
		  IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRATE, &wrq,
				 "Set Bit Rate");
		  wrq.u.bitrate.fixed = 1;
		}
	      else			/* Should be a numeric value */
		{
		  double		brate;

		  if(sscanf(args[i], "%lg", &(brate)) != 1)
		    ABORT_ARG_TYPE("Set Bit Rate", SIOCSIWRATE, args[i]);
		  if(index(args[i], 'G')) brate *= GIGA;
		  if(index(args[i], 'M')) brate *= MEGA;
		  if(index(args[i], 'k')) brate *= KILO;
		  wrq.u.bitrate.value = (long) brate;
		  wrq.u.bitrate.fixed = 1;

		  /* Check for an additional argument */
		  if(((i+1) < count) &&
		     (!strcasecmp(args[i+1], "auto")))
		    {
		      wrq.u.bitrate.fixed = 0;
		      ++i;
		    }
		  if(((i+1) < count) &&
		     (!strcasecmp(args[i+1], "fixed")))
		    {
		      wrq.u.bitrate.fixed = 1;
		      ++i;
		    }
		}
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRATE, &wrq,
			 "Set Bit Rate");
	  continue;
	}

      /* ---------- Set RTS threshold ---------- */
      if(!strncasecmp(args[i], "rts", 3))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set RTS Threshold", SIOCSIWRTS);
	  wrq.u.rts.value = -1;
	  wrq.u.rts.fixed = 1;
	  wrq.u.rts.disabled = 0;
	  if(!strcasecmp(args[i], "off"))
	    wrq.u.rts.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "auto"))
	      wrq.u.rts.fixed = 0;
	    else
	      {
		if(!strcasecmp(args[i], "fixed"))
		  {
		    /* Get old RTS threshold */
		    IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRTS, &wrq,
				   "Set RTS Threshold");
		    wrq.u.rts.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  if(sscanf(args[i], "%li", (unsigned long *) &(wrq.u.rts.value))
		     != 1)
		    ABORT_ARG_TYPE("Set RTS Threshold", SIOCSIWRTS, args[i]);
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRTS, &wrq,
			 "Set RTS Threshold");
	  continue;
	}

      /* ---------- Set fragmentation threshold ---------- */
      if(!strncmp(args[i], "frag", 4))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set Fragmentation Threshold", SIOCSIWFRAG);
	  wrq.u.frag.value = -1;
	  wrq.u.frag.fixed = 1;
	  wrq.u.frag.disabled = 0;
	  if(!strcasecmp(args[i], "off"))
	    wrq.u.frag.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "auto"))
	      wrq.u.frag.fixed = 0;
	    else
	      {
		if(!strcasecmp(args[i], "fixed"))
		  {
		    /* Get old fragmentation threshold */
		    IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFRAG, &wrq,
				   "Set Fragmentation Threshold");
		    wrq.u.frag.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  if(sscanf(args[i], "%li",
			    (unsigned long *) &(wrq.u.frag.value))
		     != 1)
		    ABORT_ARG_TYPE("Set Fragmentation Threshold", SIOCSIWFRAG,
				   args[i]);
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFRAG, &wrq,
			 "Set Fragmentation Threshold");
	  continue;
	}

      /* ---------- Set operation mode ---------- */
      if(!strcmp(args[i], "mode"))
	{
	  int	k;

	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set Mode", SIOCSIWMODE);

	  if(sscanf(args[i], "%i", &k) != 1)
	    {
	      k = 0;
	      while((k < IW_NUM_OPER_MODE) &&
		    strncasecmp(args[i], iw_operation_mode[k], 3))
		k++;
	    }
	  if((k >= IW_NUM_OPER_MODE) || (k < 0))
	    ABORT_ARG_TYPE("Set Mode", SIOCSIWMODE, args[i]);

	  wrq.u.mode = k;
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq,
			 "Set Mode");
	  continue;
	}

      /* ---------- Set Power Management ---------- */
      if(!strncmp(args[i], "power", 3))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);

	  if(!strcasecmp(args[i], "off"))
	    wrq.u.power.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old Power info */
		IW_GET_EXT_ERR(skfd, ifname, SIOCGIWPOWER, &wrq,
			       "Set Power Management");
		wrq.u.power.disabled = 0;
	      }
	    else
	      {
		double		temp;
		int		gotone = 0;
		/* Default - nope */
		wrq.u.power.flags = IW_POWER_ON;
		wrq.u.power.disabled = 0;

		/* Check value modifier */
		if(!strcasecmp(args[i], "min"))
		  {
		    wrq.u.power.flags |= IW_POWER_MIN;
		    if(++i >= count)
		      ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		  }
		else
		  if(!strcasecmp(args[i], "max"))
		    {
		      wrq.u.power.flags |= IW_POWER_MAX;
		      if(++i >= count)
			ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		    }

		/* Check value type */
		if(!strcasecmp(args[i], "period"))
		  {
		    wrq.u.power.flags |= IW_POWER_PERIOD;
		    if(++i >= count)
		      ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		  }
		else
		  if(!strcasecmp(args[i], "timeout"))
		    {
		      wrq.u.power.flags |= IW_POWER_TIMEOUT;
		      if(++i >= count)
			ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		    }

		/* Is there any value to grab ? */
		if(sscanf(args[i], "%lg", &(temp)) == 1)
		  {
		    temp *= MEGA;	/* default = s */
		    if(index(args[i], 'u')) temp /= MEGA;
		    if(index(args[i], 'm')) temp /= KILO;
		    wrq.u.power.value = (long) temp;
		    if((wrq.u.power.flags & IW_POWER_TYPE) == 0)
		      wrq.u.power.flags |= IW_POWER_PERIOD;
		    ++i;
		    gotone = 1;
		  }

		/* Now, check the mode */
		if(i < count)
		  {
		    if(!strcasecmp(args[i], "all"))
		      wrq.u.power.flags |= IW_POWER_ALL_R;
		    if(!strncasecmp(args[i], "unicast", 4))
		      wrq.u.power.flags |= IW_POWER_UNICAST_R;
		    if(!strncasecmp(args[i], "multicast", 5))
		      wrq.u.power.flags |= IW_POWER_MULTICAST_R;
		    if(!strncasecmp(args[i], "force", 5))
		      wrq.u.power.flags |= IW_POWER_FORCE_S;
		    if(!strcasecmp(args[i], "repeat"))
		      wrq.u.power.flags |= IW_POWER_REPEATER;
		    if(wrq.u.power.flags & IW_POWER_MODE)
		      {
			++i;
			gotone = 1;
		      }
		  }
		if(!gotone)
		  ABORT_ARG_TYPE("Set Power Management", SIOCSIWPOWER,
				 args[i]);
		--i;
	      }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWPOWER, &wrq,
		       "Set Power Management");
	  continue;
  	}

#if WIRELESS_EXT > 9
      /* ---------- Set Transmit-Power ---------- */
      if(!strncmp(args[i], "txpower", 3))
	{
	  struct iw_range	range;

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Tx Power", SIOCSIWTXPOW);

	  /* Extract range info */
	  if(iw_get_range_info(skfd, ifname, &range) < 0)
	    memset(&range, 0, sizeof(range));

	  /* Prepare the request */
	  wrq.u.txpower.value = -1;
	  wrq.u.txpower.fixed = 1;
	  wrq.u.txpower.disabled = 0;
	  wrq.u.data.flags = IW_TXPOW_DBM;
	  if(!strcasecmp(args[i], "off"))
	    wrq.u.txpower.disabled = 1;	/* i.e. turn radio off */
	  else
	    if(!strcasecmp(args[i], "auto"))
	      wrq.u.txpower.fixed = 0;	/* i.e. use power control */
	    else
	      {
		if(!strcasecmp(args[i], "fixed"))
		  {
		    /* Get old tx-power */
		    IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
				   "Set Tx Power");
		    wrq.u.txpower.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  {
		    int		power;
		    int		ismwatt = 0;

		    /* Get the value */
		    if(sscanf(args[i], "%i", &(power)) != 1)
		      ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW, args[i]);

		    /* Check if milliwatt */
		    ismwatt = (index(args[i], 'm') != NULL);

		    /* Convert */
		    if(range.txpower_capa & IW_TXPOW_MWATT)
		      {
			if(!ismwatt)
			  power = iw_dbm2mwatt(power);
			wrq.u.data.flags = IW_TXPOW_MWATT;
		      }
		    else
		      {
			if(ismwatt)
			  power = iw_mwatt2dbm(power);
			wrq.u.data.flags = IW_TXPOW_DBM;
		      }
		    wrq.u.txpower.value = power;

		    /* Check for an additional argument */
		    if(((i+1) < count) &&
		       (!strcasecmp(args[i+1], "auto")))
		      {
			wrq.u.txpower.fixed = 0;
			++i;
		      }
		    if(((i+1) < count) &&
		       (!strcasecmp(args[i+1], "fixed")))
		      {
			wrq.u.txpower.fixed = 1;
			++i;
		      }
		  }
	      }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq,
			 "Set Tx Power");
	  continue;
	}
#endif

#if WIRELESS_EXT > 10
      /* ---------- Set Retry limit ---------- */
      if(!strncmp(args[i], "retry", 3))
	{
	  double		temp;
	  int		gotone = 0;

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);

	  /* Default - nope */
	  wrq.u.retry.flags = IW_RETRY_LIMIT;
	  wrq.u.retry.disabled = 0;

	  /* Check value modifier */
	  if(!strcasecmp(args[i], "min"))
	    {
	      wrq.u.retry.flags |= IW_RETRY_MIN;
	      if(++i >= count)
		ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	    }
	  else
	    if(!strcasecmp(args[i], "max"))
	      {
		wrq.u.retry.flags |= IW_RETRY_MAX;
		if(++i >= count)
		  ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	      }

	  /* Check value type */
	  if(!strcasecmp(args[i], "limit"))
	    {
	      wrq.u.retry.flags |= IW_RETRY_LIMIT;
	      if(++i >= count)
		ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	    }
	  else
	    if(!strncasecmp(args[i], "lifetime", 4))
	      {
		wrq.u.retry.flags &= ~IW_RETRY_LIMIT;
		wrq.u.retry.flags |= IW_RETRY_LIFETIME;
		if(++i >= count)
		  ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	      }

	  /* Is there any value to grab ? */
	  if(sscanf(args[i], "%lg", &(temp)) == 1)
	    {
	      /* Limit is absolute, on the other hand lifetime is seconds */
	      if(!(wrq.u.retry.flags & IW_RETRY_LIMIT))
		{
		  /* Normalise lifetime */
		  temp *= MEGA;	/* default = s */
		  if(index(args[i], 'u')) temp /= MEGA;
		  if(index(args[i], 'm')) temp /= KILO;
		}
	      wrq.u.retry.value = (long) temp;
	      ++i;
	      gotone = 1;
	    }

	  if(!gotone)
	    ABORT_ARG_TYPE("Set Retry Limit", SIOCSIWRETRY, args[i]);
	  --i;

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRETRY, &wrq,
			 "Set Retry Limit");
	  continue;
	}

#endif	/* WIRELESS_EXT > 10 */

      /* ---------- Other ---------- */
      /* Here we have an unrecognised arg... */
      fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n",
	      args[i]);
      return(-1);
    }		/* for(index ... */
  return(0);
}
Beispiel #24
0
/*
 * Print the number of available encryption key for the device
 */
static int
print_keys_info(int		skfd,
		char *		ifname,
		char *		args[],		/* Command line args */
		int		count)		/* Args count */
{
  struct iwreq		wrq;
  struct iw_range	range;
  unsigned char		key[IW_ENCODING_TOKEN_MAX];
  int			k;
  char			buffer[128];

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Extract range info */
  if(iw_get_range_info(skfd, ifname, &range) < 0)
      fprintf(stderr, "%-8.16s  no encryption keys information.\n\n",
		      ifname);
  else
    {
      printf("%-8.16s  ", ifname);
      /* Print key sizes */
      if((range.num_encoding_sizes > 0) &&
	 (range.num_encoding_sizes < IW_MAX_ENCODING_SIZES))
	{
	  printf("%d key sizes : %d", range.num_encoding_sizes,
		 range.encoding_size[0] * 8);
	  /* Print them all */
	  for(k = 1; k < range.num_encoding_sizes; k++)
	    printf(", %d", range.encoding_size[k] * 8);
	  printf("bits\n          ");
	}
      /* Print the keys and associate mode */
      printf("%d keys available :\n", range.max_encoding_tokens);
      for(k = 1; k <= range.max_encoding_tokens; k++)
	{
	  wrq.u.data.pointer = (caddr_t) key;
	  wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
	  wrq.u.data.flags = k;
	  if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) < 0)
	    {
	      fprintf(stderr, "Error reading wireless keys (SIOCGIWENCODE): %s\n", strerror(errno));
	      break;
	    }
	  if((wrq.u.data.flags & IW_ENCODE_DISABLED) ||
	     (wrq.u.data.length == 0))
	    printf("\t\t[%d]: off\n", k);
	  else
	    {
	      /* Display the key */
	      iw_print_key(buffer, sizeof(buffer),
			   key, wrq.u.data.length, wrq.u.data.flags);
	      printf("\t\t[%d]: %s", k, buffer);

	      /* Other info... */
	      printf(" (%d bits)", wrq.u.data.length * 8);
	      printf("\n");
	    }
	}
      /* Print current key and mode */
      wrq.u.data.pointer = (caddr_t) key;
      wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
      wrq.u.data.flags = 0;	/* Set index to zero to get current */
      if(iw_get_ext(skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
	{
	  /* Note : if above fails, we have already printed an error
	   * message int the loop above */
	  printf("          Current Transmit Key: [%d]\n",
		 wrq.u.data.flags & IW_ENCODE_INDEX);
	  if(wrq.u.data.flags & IW_ENCODE_RESTRICTED)
	    printf("          Security mode:restricted\n");
	  if(wrq.u.data.flags & IW_ENCODE_OPEN)
	    printf("          Security mode:open\n");
	}

      /* Print WPA/802.1x/802.11i security parameters */
      if(range.we_version_compiled > 17)
	{
	  /* Display advance encryption capabilities */
	  if(range.enc_capa)
	    {
	      const char *	auth_string[] = { "WPA",
						  "WPA2",
						  "CIPHER TKIP",
						  "CIPHER CCMP" };
	      const int		auth_num = (sizeof(auth_string) /
					    sizeof(auth_string[1]));
	      int		i;
	      int		mask = 0x1;

	      printf("          Authentication capabilities :\n");
	      for(i = 0; i < auth_num; i++)
		{
		  if(range.enc_capa & mask)
		    printf("\t\t%s\n", auth_string[i]);
		  mask <<= 1;
		}
	    }

	  /* Current values for authentication */
	  wrq.u.param.flags = IW_AUTH_KEY_MGMT;
	  if(iw_get_ext(skfd, ifname, SIOCGIWAUTH, &wrq) >= 0)
	      printf("          Current key_mgmt:0x%X\n",
		     wrq.u.param.value);

	  wrq.u.param.flags = IW_AUTH_CIPHER_PAIRWISE;
	  if(iw_get_ext(skfd, ifname, SIOCGIWAUTH, &wrq) >= 0)
	      printf("          Current cipher_pairwise:0x%X\n",
		     wrq.u.param.value);

	  wrq.u.param.flags = IW_AUTH_CIPHER_GROUP;
	  if(iw_get_ext(skfd, ifname, SIOCGIWAUTH, &wrq) >= 0)
	    printf("          Current cipher_group:0x%X\n",
		   wrq.u.param.value);
	}

     printf("\n\n");
    }
  return(0);
}
Beispiel #25
0
int netproc_scandevice(int sockfd, int iwsockfd, FILE *fp, NETDEVLIST_PTR *netdev_list)
{
	char buffer[512];
	int count = 0;
	int prx_idx, ptx_idx, brx_idx, btx_idx;
	gulong in_packets, out_packets, in_bytes, out_bytes;
	NETDEVLIST_PTR devptr = NULL;

	/* interface information */
	struct ifreq ifr;
	struct ethtool_test edata;
	iwstats iws;
	char *status;
	char *name;
	struct iw_range iwrange;
	int has_iwrange = 0;

	status = fgets (buffer, sizeof(buffer), fp);
	if (!status)
		ERR("netstat: netproc_scnadevice(): Error reading first line from stream!\n");
	status = fgets (buffer, sizeof(buffer), fp);
	if (!status)
		ERR("netstat: netproc_scnadevice(): Error reading second line from stream!\n");
	netproc_parse_stats_header(buffer, &prx_idx, &ptx_idx, &brx_idx, &btx_idx);

	while (fgets(buffer, sizeof(buffer), fp)) {
		/* getting interface name */
		name = buffer;
		while (g_ascii_isspace(name[0])) {
			name++;
		}

		/* reading packet infomation */
		status = netproc_parse_ifname(name);
		netproc_parse_status(status, prx_idx, ptx_idx, &in_packets, &out_packets,
				     brx_idx, btx_idx, &in_bytes, &out_bytes);

		/* check interface hw_type */
		bzero(&ifr, sizeof(ifr));
		strncpy(ifr.ifr_name, name, strlen(name));
  		ifr.ifr_name[strlen(name)+1] = '\0';
		if (ioctl(sockfd, SIOCGIFHWADDR, &ifr)<0)
			continue;

		/* hw_types is not Ethernet and PPP */
		if (ifr.ifr_hwaddr.sa_family!=ARPHRD_ETHER&&ifr.ifr_hwaddr.sa_family!=ARPHRD_PPP)
			continue;

		/* detecting new interface */
		if ((devptr = netproc_netdevlist_find(*netdev_list, name))==NULL) {
			/* check wireless device */
			has_iwrange = (iw_get_range_info(iwsockfd, name, &iwrange)>=0);
			if (!(has_iwrange) || (iwrange.we_version_compiled < 14))
				netproc_netdevlist_add(netdev_list, name, in_bytes, in_packets, out_bytes, out_packets, FALSE);
			else
				netproc_netdevlist_add(netdev_list, name, in_bytes, in_packets, out_bytes, out_packets, TRUE);

			devptr = netproc_netdevlist_find(*netdev_list, name);

			/* MAC Address */
			devptr->info.mac = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
					ifr.ifr_hwaddr.sa_data[0] & 0377,
					ifr.ifr_hwaddr.sa_data[1] & 0377,
					ifr.ifr_hwaddr.sa_data[2] & 0377,
					ifr.ifr_hwaddr.sa_data[3] & 0377,
					ifr.ifr_hwaddr.sa_data[4] & 0377,
					ifr.ifr_hwaddr.sa_data[5] & 0377);
		} else {
			/* Setting device status and update flags */
			if (devptr->info.recv_packets!=in_packets&&devptr->info.trans_packets!=out_packets) {
				if (devptr->info.status!=NETDEV_STAT_BOTHRS)
					devptr->info.updated = TRUE;
			
				devptr->info.status = NETDEV_STAT_BOTHRS;
			} else if (devptr->info.recv_packets!=in_packets) {
				if (devptr->info.status!=NETDEV_STAT_RECVDATA)
					devptr->info.updated = TRUE;

				devptr->info.status = NETDEV_STAT_RECVDATA;
			} else if (devptr->info.trans_packets!=out_packets) {
				if (devptr->info.status!=NETDEV_STAT_SENDDATA)
					devptr->info.updated = TRUE;

				devptr->info.status = NETDEV_STAT_SENDDATA;
			} else {
				if (devptr->info.status!=NETDEV_STAT_NORMAL)
					devptr->info.updated = TRUE;

				devptr->info.status = NETDEV_STAT_NORMAL;
			}

			/* Recording r/t information */
			devptr->info.recv_bytes = in_bytes;
			devptr->info.recv_packets = in_packets;
			devptr->info.trans_bytes = out_bytes;
			devptr->info.trans_packets = out_packets;

			/* give device a life */
			devptr->info.alive = TRUE;
		}

		/* Enable */
		bzero(&ifr, sizeof(ifr));
		strcpy(ifr.ifr_name, devptr->info.ifname);
		ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
		if (ioctl(sockfd, SIOCGIFFLAGS, &ifr)>=0) {
			devptr->info.flags = ifr.ifr_flags;
			if (ifr.ifr_flags & IFF_UP) {
				devptr->info.enable = TRUE;
				devptr->info.updated = TRUE;
			} else {
				devptr->info.enable = FALSE;
				devptr->info.updated = TRUE;
			}

			if (devptr->info.enable) {
				/* Workaround for Atheros Cards */
				if (strncmp(devptr->info.ifname, "ath", 3)==0)
					wireless_refresh(iwsockfd, devptr->info.ifname);
				
				/* plug */
				bzero(&ifr, sizeof(ifr));
				strcpy(ifr.ifr_name, devptr->info.ifname);
				ifr.ifr_name[IF_NAMESIZE - 1] = '\0';

				edata.cmd = 0x0000000a;
				ifr.ifr_data = (caddr_t)&edata;
				if (ioctl(sockfd, SIOCETHTOOL, &ifr)<0) {
					/* using IFF_RUNNING instead due to system doesn't have ethtool or working in non-root */
					if (devptr->info.flags & IFF_RUNNING) {
						if (!devptr->info.plug) {
							devptr->info.plug = TRUE;
							devptr->info.updated = TRUE;
						}
					} else if (devptr->info.plug) {
						devptr->info.plug = FALSE;
						devptr->info.updated = TRUE;
					}
				} else {
					if (edata.data) {
						if (!devptr->info.plug) {
							devptr->info.plug = TRUE;
							devptr->info.updated = TRUE;
						}
					} else if (devptr->info.plug) {
						devptr->info.plug = FALSE;
						devptr->info.updated = TRUE;
					}
				}

				/* get network information */
				if (devptr->info.enable&&devptr->info.plug) {
					if (devptr->info.flags & IFF_RUNNING) {
						/* release old information */
						g_free(devptr->info.ipaddr);
						g_free(devptr->info.bcast);
						g_free(devptr->info.mask);

						/* IP Address */
						bzero(&ifr, sizeof(ifr));
						strcpy(ifr.ifr_name, devptr->info.ifname);
						ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
						if (ioctl(sockfd, SIOCGIFADDR, &ifr)<0)
							devptr->info.ipaddr = g_strdup("0.0.0.0");
						else
							devptr->info.ipaddr = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));

						/* Point-to-Porint Address */
						if (devptr->info.flags & IFF_POINTOPOINT) {
							bzero(&ifr, sizeof(ifr));
							strcpy(ifr.ifr_name, devptr->info.ifname);
							ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
							if (ioctl(sockfd, SIOCGIFDSTADDR, &ifr)<0)
								devptr->info.dest = NULL;
							else
								devptr->info.dest = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_dstaddr)->sin_addr));
						}

						/* Broadcast */
						if (devptr->info.flags & IFF_BROADCAST) {
							bzero(&ifr, sizeof(ifr));
							strcpy(ifr.ifr_name, devptr->info.ifname);
							ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
							if (ioctl(sockfd, SIOCGIFBRDADDR, &ifr)<0)
								devptr->info.bcast = NULL;
							else
								devptr->info.bcast = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_broadaddr)->sin_addr));
						}

						/* Netmask */
						bzero(&ifr, sizeof(ifr));
						strcpy(ifr.ifr_name, devptr->info.ifname);
						ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
						if (ioctl(sockfd, SIOCGIFNETMASK, &ifr)<0)
							devptr->info.mask = NULL;
						else
							devptr->info.mask = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));

						/* Wireless Information */
						if (devptr->info.wireless) {
							struct wireless_config wconfig;

							/* get wireless config */
							if (iw_get_basic_config(iwsockfd, devptr->info.ifname, &wconfig)>=0) {
								/* Protocol */
								devptr->info.protocol = g_strdup(wconfig.name);
								/* ESSID */
								devptr->info.essid = g_strdup(wconfig.essid);

								/* Signal Quality */
								iw_get_stats(iwsockfd, devptr->info.ifname, &iws, &iwrange, has_iwrange);
								devptr->info.quality = rint((log (iws.qual.qual) / log (92)) * 100.0);
							}
						}

						/* check problem connection */
						if (strcmp(devptr->info.ipaddr, "0.0.0.0")==0) {
							devptr->info.status = NETDEV_STAT_PROBLEM;
							/* has connection problem  */
							if (devptr->info.connected) {
								devptr->info.connected = FALSE;
								devptr->info.updated = TRUE;
							}
						} else if (!devptr->info.connected) {
								devptr->info.status = NETDEV_STAT_NORMAL;
								devptr->info.connected = TRUE;
								devptr->info.updated = TRUE;
						}
					} else {
						/* has connection problem  */
						devptr->info.status = NETDEV_STAT_PROBLEM;
						if (devptr->info.connected) {
							devptr->info.connected = FALSE;
							devptr->info.updated = TRUE;
						}
					}
				}
			}
		}

		devptr = NULL;
		count++;
	}

	rewind(fp);
	fflush(fp);

	return count;
}
Beispiel #26
0
/*
 * Print Retry info for each device
 */
static int
print_retry_info(int		skfd,
		 char *		ifname,
		 char *		args[],		/* Command line args */
		 int		count)		/* Args count */
{
  struct iwreq		wrq;
  struct iw_range	range;
  char			buffer[128];

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Extract range info */
  if((iw_get_range_info(skfd, ifname, &range) < 0) ||
     (range.we_version_compiled < 11))
    fprintf(stderr, "%-8.16s  no retry limit/lifetime information.\n\n",
	    ifname);
  else
    {
      printf("%-8.16s  ", ifname);

      /* Display min/max limit availables */
      if(range.retry_flags & IW_RETRY_LIMIT)
	{
	  int	flags = (range.retry_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
	  /* Display if auto or fixed */
	  if(range.retry_flags & IW_RETRY_MIN)
	    printf("Auto  limit    ; ");
	  else
	    printf("Fixed limit    ; ");
	  /* Print the range */
	  iw_print_retry_value(buffer, sizeof(buffer),
			       range.min_retry, flags | IW_RETRY_MIN);
	  printf("%s\n                           ", buffer);
	  iw_print_retry_value(buffer, sizeof(buffer),
			       range.max_retry, flags | IW_RETRY_MAX);
	  printf("%s\n          ", buffer);
	  
	}
      /* Display min/max lifetime availables */
      if(range.r_time_flags & IW_RETRY_LIFETIME)
	{
	  int	flags = (range.r_time_flags & ~(IW_RETRY_MIN | IW_RETRY_MAX));
	  /* Display if auto or fixed */
	  if(range.r_time_flags & IW_RETRY_MIN)
	    printf("Auto  lifetime ; ");
	  else
	    printf("Fixed lifetime ; ");
	  /* Print the range */
	  iw_print_retry_value(buffer, sizeof(buffer),
			       range.min_r_time, flags | IW_RETRY_MIN);
	  printf("%s\n                           ", buffer);
	  iw_print_retry_value(buffer, sizeof(buffer),
			       range.max_r_time, flags | IW_RETRY_MAX);
	  printf("%s\n          ", buffer);
	  
	}

      /* Get current retry settings */
      wrq.u.retry.flags = 0;
      if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
	{
	  int	flags = wrq.u.retry.flags;

	  /* Is it disabled ? */
	  if(wrq.u.retry.disabled)
	    printf("Current mode:off\n          ");
	  else
	    {
	      int	retry_mask = 0;

	      /* Let's check the mode */
	      printf("Current mode:on\n                 ");

	      /* Let's check the value and its type */
	      if(wrq.u.retry.flags & IW_RETRY_TYPE)
		{
		  iw_print_retry_value(buffer, sizeof(buffer),
				       wrq.u.retry.value, wrq.u.retry.flags);
		  printf("%s\n                 ", buffer);
		}

	      /* If we have been returned a MIN value, ask for the MAX */
	      if(flags & IW_RETRY_MIN)
		retry_mask = IW_RETRY_MAX;
	      /* If we have been returned a MAX value, ask for the MIN */
	      if(flags & IW_RETRY_MAX)
		retry_mask = IW_RETRY_MIN;
	      /* If we have something to ask for... */
	      if(retry_mask)
		get_retry_value(skfd, ifname, &wrq, retry_mask,
				buffer, sizeof(buffer));

	      /* And if we have both a period and a timeout, ask the other */
	      retry_mask = (range.retry_capa & (~(wrq.u.retry.flags) &
					  IW_RETRY_TYPE));
	      if(retry_mask)
		{
		  int	base_mask = retry_mask;
		  flags = get_retry_value(skfd, ifname, &wrq, retry_mask,
					  buffer, sizeof(buffer));
		  retry_mask = 0;

		  /* If we have been returned a MIN value, ask for the MAX */
		  if(flags & IW_RETRY_MIN)
		    retry_mask = IW_RETRY_MAX | base_mask;
		  /* If we have been returned a MAX value, ask for the MIN */
		  if(flags & IW_RETRY_MAX)
		    retry_mask = IW_RETRY_MIN | base_mask;
		  /* If we have something to ask for... */
		  if(retry_mask)
		    get_retry_value(skfd, ifname, &wrq, retry_mask,
				    buffer, sizeof(buffer));
		}
	    }
	}
      printf("\n");
    }
  return(0);
}
Beispiel #27
0
/*
 * Set Tx Power
 */
static int
set_txpower_info(int		skfd,
		char *		ifname,
		char *		args[],		/* Command line args */
		int		count)		/* Args count */
{
  struct iwreq		wrq;
  int			i = 1;

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Prepare the request */
  wrq.u.txpower.value = -1;
  wrq.u.txpower.fixed = 1;
  wrq.u.txpower.disabled = 0;
  wrq.u.txpower.flags = IW_TXPOW_DBM;

  if(!strcasecmp(args[0], "off"))
    wrq.u.txpower.disabled = 1;	/* i.e. turn radio off */
  else
    if(!strcasecmp(args[0], "auto"))
      wrq.u.txpower.fixed = 0;	/* i.e. use power control */
    else
      {
	if(!strcasecmp(args[0], "on"))
	  {
	    /* Get old tx-power */
	    if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) < 0)
	      return(IWERR_GET_EXT);
	    wrq.u.txpower.disabled = 0;
	  }
	else
	  {
	    if(!strcasecmp(args[0], "fixed"))
	      {
		/* Get old tx-power */
		if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) < 0)
		  return(IWERR_GET_EXT);
		wrq.u.txpower.fixed = 1;
		wrq.u.txpower.disabled = 0;
	      }
	    else			/* Should be a numeric value */
	      {
		int		power;
		int		ismwatt = 0;
		struct iw_range	range;

		/* Extract range info to do proper conversion */
		if(iw_get_range_info(skfd, ifname, &range) < 0)
		  memset(&range, 0, sizeof(range));

		/* Get the value */
		if(sscanf(args[0], "%i", &(power)) != 1)
		  {
		    errarg = 0;
		    return(IWERR_ARG_TYPE);
		  }

		/* Check if milliWatt
		 * We authorise a single 'm' as a shorthand for 'mW',
		 * on the other hand a 'd' probably means 'dBm'... */
		ismwatt = ((strchr(args[0], 'm') != NULL)
			   && (strchr(args[0], 'd') == NULL));

		/* We could check 'W' alone... Another time... */

		/* Convert */
		if(range.txpower_capa & IW_TXPOW_RELATIVE)
		  {
		    /* Can't convert */
		    if(ismwatt)
		      {
			errarg = 0;
			return(IWERR_ARG_TYPE);
		      }
		    wrq.u.txpower.flags = IW_TXPOW_RELATIVE;
		  }
		else
		  if(range.txpower_capa & IW_TXPOW_MWATT)
		    {
		      if(!ismwatt)
			power = iw_dbm2mwatt(power);
		      wrq.u.txpower.flags = IW_TXPOW_MWATT;
		    }
		  else
		    {
		      if(ismwatt)
			power = iw_mwatt2dbm(power);
		      wrq.u.txpower.flags = IW_TXPOW_DBM;
		    }
		wrq.u.txpower.value = power;

		/* Check for an additional argument */
		if((i < count) && (!strcasecmp(args[i], "auto")))
		  {
		    wrq.u.txpower.fixed = 0;
		    ++i;
		  }
		if((i < count) && (!strcasecmp(args[i], "fixed")))
		  {
		    wrq.u.txpower.fixed = 1;
		    ++i;
		  }
	      }
	  }
      }

  if(iw_set_ext(skfd, ifname, SIOCSIWTXPOW, &wrq) < 0)
    return(IWERR_SET_EXT);

  /* Var args */
  return(i);
}
Beispiel #28
0
void CWextHW::readSignalQuality() {
	if ( (m_wextFd == -1) ) {
		return;
	}
	struct iw_range range;
	memset(&range,0,sizeof(struct iw_range));
	int hasRange = 0;
	iwstats stats;
	memset(&stats,0,sizeof(iwstats));
	WextRawScan res;
	/* workaround */
	struct wireless_config wifiConfig;
	memset(&wifiConfig,0,sizeof(struct wireless_config));
	/* Get basic information */ 
	if(iw_get_basic_config(m_wextFd, m_ifname.toAscii().constData(), &wifiConfig) < 0) {
		/* If no wireless name : no wireless extensions */ 
		/* But let's check if the interface exists at all */ 
		struct ifreq ifr;
		memset(&ifr,0,sizeof(struct ifreq)); 
	
		strncpy(ifr.ifr_name, m_ifname.toAscii().data(), IFNAMSIZ); 
		if(ioctl(m_wextFd, SIOCGIFFLAGS, &ifr) < 0) 
			qWarning() << tr("(Wireless Extension) No device present");
		else
			qWarning() << tr("(Wireless Extension) device not supported");
		return;
	}
	qDebug() << "Fetched basic config.";

	//We encode frequency in mhz;
	//kernel encodes as double; (hopefully always in hz)
	//But better test this:
	res.freq = -1;
	if (wifiConfig.has_freq) {
		if ( ( (wifiConfig.freq/1e9) < 10.0 ) && ( (wifiConfig.freq/1e9) > 0.0 ) ) {
			res.freq = (int) (wifiConfig.freq/1e6);
		}
	}
	
	struct iwreq wrq;
	memset(&wrq,0,sizeof(struct iwreq));
	
	/* Get AP address */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWAP, &wrq) >= 0) {
		//Add mac address of current ap;
		res.bssid = libnutcommon::MacAddress((ether_addr*)wrq.u.ap_addr.sa_data);
		qDebug() << "Got AP: " << res.bssid.toString();
	}
	
	/* Get ssid */
	quint8 * buffer = new quint8[IW_ESSID_MAX_SIZE];
	memset(buffer, '\0', IW_ESSID_MAX_SIZE);
	wrq.u.essid.pointer = (void *)buffer;
	wrq.u.essid.length = IW_ESSID_MAX_SIZE;
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWESSID, &wrq) >= 0) {
		if (wrq.u.essid.length > IW_ESSID_MAX_SIZE)
			wrq.u.essid.length = IW_ESSID_MAX_SIZE;
		if (wrq.u.essid.flags) {
			/* Does it have an ESSID index ? */
			if ( wrq.u.essid.pointer && wrq.u.essid.length ) {
				if ( (wrq.u.essid.flags & IW_ENCODE_INDEX) > 1) {
					res.ssid = QString("%1 [%2]").arg(QString::fromAscii((char*) wrq.u.essid.pointer, wrq.u.essid.length), QString::number(wrq.u.essid.flags & IW_ENCODE_INDEX));
				}
				else {
					res.ssid = QString::fromAscii((char*) wrq.u.essid.pointer, wrq.u.essid.length);
				}
			}
			else {
				res.ssid = "N/A";
			}
		}
		qDebug() << "Got ssid: " << res.ssid;
	}
	delete[] buffer;
	
	/* Get bit rate */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWRATE, &wrq) >= 0) {
		res.bitrates.append((qint32) wrq.u.bitrate.value);
		qDebug() << "Got bit rate: " << res.bitrates[0];
	}
	
	/* Get Power Management settings */
	wrq.u.power.flags = 0;
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWPOWER, &wrq) >= 0) {
		qDebug() << "Got power";
	}
	/* workaround */
	
	
	/* Get range stuff */
	qDebug() << QString("Getting range stuff for %1").arg(m_ifname.toAscii().data());
	if (iw_get_range_info(m_wextFd, m_ifname.toAscii().data(), &range) >= 0) {
		hasRange = 1;
		qDebug() << "Success readWirelessInfo getrange" << strerror(errno);
	}
	else { //This is VERY strange: we always get the "operation not permitted" error, although iw_get_range() worked
		qDebug() << QString("Error \"hasRange == 0\" (%1)").arg(strerror(errno));
	}
	res.hasRange = hasRange;
	if (errno == EAGAIN) {
		m_sqTimeOutCount++;
		qDebug() << QString("Getting range stuff failed (%1)").arg(strerror(errno));
		if ( (m_sqTimeOutCount > 10) && m_sqPollrate < 1000) {
			setSignalQualityPollRate(10000);
		}
		else if (m_sqTimeOutCount > 10) { //Fast polling disabled, but still EAGAIN errors
			//Seems the kernel does not care about our calls
			killTimer(m_sqTimerId);
			m_sqTimerId = -1;
		}
		return;
	}
	
	qDebug() << "Got range stuff";
	

	//Set supported Frequencies if the list is not empty;
	if (m_supportedFrequencies.isEmpty() && hasRange) {
		qDebug() << range.num_frequency;
		qDebug() << "Printing Frequency information";
		quint32 m;
		quint16 e;
		quint32 freqinmhz;
		for (int i=0; i < range.num_channels; i++) {
			m = (quint32) range.freq[i].m;
			e = (quint16) range.freq[i].e;
			freqinmhz = m;
			for (int j=0; j < 9-e-3; j++) {
				freqinmhz = freqinmhz/10;
			}
			if (!m_supportedFrequencies.contains(freqinmhz)) { //Only add frequency that are not in our list
				m_supportedFrequencies.append(freqinmhz);
			}
			qDebug() << m << e << freqinmhz << frequencyToChannel(freqinmhz);
		}
		qDebug() << "Done printing";
	}
	else {
		qDebug() << "m_supportedFrequencies not set";
	}
	
	if (hasRange) {
		res.maxquality.level = (quint8) range.max_qual.level;
		res.maxquality.qual = (quint8) range.max_qual.qual;
		res.maxquality.noise = (quint8) range.max_qual.noise;
		res.maxquality.updated = (quint8) range.max_qual.updated;
		qDebug() << "RANGE: " << res.maxquality.level  << res.maxquality.qual << res.maxquality.noise << res.maxquality.updated;
	}
	else {
		res.maxquality.level = 0;
		res.maxquality.qual = 0;
		res.maxquality.noise = 0;
		res.maxquality.updated = 0;
		qDebug() << "Range information are not available";
	}
	if ( (hasRange) && (range.we_version_compiled > 11) ) {
		struct iwreq wrq;
		memset(&wrq,0,sizeof(struct iwreq));
		wrq.u.data.pointer = (caddr_t) &stats;
		wrq.u.data.length = sizeof(struct iw_statistics);
		wrq.u.data.flags = 1; // Clear updated flag
		strncpy(wrq.ifr_name, m_ifname.toAscii().data(), IFNAMSIZ);
		
		qDebug() << "Getting wireless stats";
		if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWSTATS, &wrq) < 0) {
			qWarning() << tr("Error occured while fetching wireless info: ") << strerror(errno);
		}
		else { //Stats fetched
			qDebug() << "Stats fetched";
			res.quality.level = (quint8) stats.qual.level;
			res.quality.qual = (quint8) stats.qual.qual;
			res.quality.noise = (quint8) stats.qual.noise;
			res.quality.updated = (quint8) stats.qual.updated;
			qDebug() << "STATS: " << res.quality.level << res.quality.qual << res.quality.noise << res.quality.updated;
			m_sq = convertValues(res);
			qDebug() << "Emittig m_signalQualityUpdated()";
			if (m_sqPollrate < 1000) {
				setSignalQualityPollRate(10000);
				emit message(tr("Auto-resetting timer to 10 seconds"));
			}
			emit signalQualityUpdated(m_sq);
		}
	}
	else if (range.we_version_compiled <= 11) {
		emit message(tr("Cannot fetch wireless information as your wireless extension is too old"));
		emit message(tr("Think about updating your kernel (it's way too old)"));
	}
	else {
		qDebug() << "Error while trying to fetch wireless information" << strerror(errno);
		qDebug() << "Wireless Extension socket file descriptor was: " << m_wextFd;
	}
}
Beispiel #29
0
/*
 * Get wireless informations & config from the device driver
 * We will call all the classical wireless ioctl on the driver through
 * the socket to know what is supported and to get the settings...
 */
static int
get_info(int			skfd,
	 char *			ifname,
	 struct wireless_info *	info)
{
  struct iwreq		wrq;

  memset((char *) info, 0, sizeof(struct wireless_info));

  /* Get basic information */
  if(iw_get_basic_config(skfd, ifname, &(info->b)) < 0)
    {
      /* If no wireless name : no wireless extensions */
      /* But let's check if the interface exists at all */
      struct ifreq ifr;

      strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
      if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
	return(-ENODEV);
      else
	return(-ENOTSUP);
    }

  /* Get ranges */
  if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
    info->has_range = 1;

  /* Get AP address */
  if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
    {
      info->has_ap_addr = 1;
      memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
    }

  /* Get bit rate */
  if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
    {
      info->has_bitrate = 1;
      memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
    }

  /* Get Power Management settings */
  wrq.u.power.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
    {
      info->has_power = 1;
      memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
    }

  /* Get stats */
  if(iw_get_stats(skfd, ifname, &(info->stats),
		  &info->range, info->has_range) >= 0)
    {
      info->has_stats = 1;
    }

#ifndef WE_ESSENTIAL
  /* Get NickName */
  wrq.u.essid.pointer = (caddr_t) info->nickname;
  wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
  wrq.u.essid.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
    if(wrq.u.data.length > 1)
      info->has_nickname = 1;

  if((info->has_range) && (info->range.we_version_compiled > 9))
    {
      /* Get Transmit Power */
      if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
	{
	  info->has_txpower = 1;
	  memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
	}
    }

  /* Get sensitivity */
  if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
    {
      info->has_sens = 1;
      memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
    }

  if((info->has_range) && (info->range.we_version_compiled > 10))
    {
      /* Get retry limit/lifetime */
      if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
	{
	  info->has_retry = 1;
	  memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
	}
    }

  /* Get RTS threshold */
  if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
    {
      info->has_rts = 1;
      memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
    }

  /* Get fragmentation threshold */
  if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
    {
      info->has_frag = 1;
      memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
    }
#endif	/* WE_ESSENTIAL */

  return(0);
}
Beispiel #30
0
/*
 * Perform a scanning on one device
 */
static int
print_scanning_info(int		skfd,
		    char *	ifname,
		    char *	args[],		/* Command line args */
		    int		count)		/* Args count */
{
  struct iwreq		wrq;
  unsigned char *	buffer = NULL;		/* Results */
  int			buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
  struct iw_range	range;
  int			has_range;
  struct timeval	tv;				/* Select timeout */
  int			timeout = 15000000;		/* 15s */

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Get range stuff */
  has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);

  /* Check if the interface could support scanning. */
  if((!has_range) || (range.we_version_compiled < 14))
    {
      fprintf(stderr, "%-8.16s  Interface doesn't support scanning.\n\n",
	      ifname);
      return(-1);
    }

  /* Init timeout value -> 250ms*/
  tv.tv_sec = 0;
  tv.tv_usec = 250000;

  /*
   * Here we should look at the command line args and set the IW_SCAN_ flags
   * properly
   */
  wrq.u.data.pointer = NULL;		/* Later */
  wrq.u.data.flags = 0;
  wrq.u.data.length = 0;

  /* Initiate Scanning */
  if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
    {
      if(errno != EPERM)
	{
	  fprintf(stderr, "%-8.16s  Interface doesn't support scanning : %s\n\n",
		  ifname, strerror(errno));
	  return(-1);
	}
      /* If we don't have the permission to initiate the scan, we may
       * still have permission to read left-over results.
       * But, don't wait !!! */
#if 0
      /* Not cool, it display for non wireless interfaces... */
      fprintf(stderr, "%-8.16s  (Could not trigger scanning, just reading left-over results)\n", ifname);
#endif
      tv.tv_usec = 0;
    }
  timeout -= tv.tv_usec;

  /* Forever */
  while(1)
    {
      fd_set		rfds;		/* File descriptors for select */
      int		last_fd;	/* Last fd */
      int		ret;

      /* Guess what ? We must re-generate rfds each time */
      FD_ZERO(&rfds);
      last_fd = -1;

      /* In here, add the rtnetlink fd in the list */

      /* Wait until something happens */
      ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);

      /* Check if there was an error */
      if(ret < 0)
	{
	  if(errno == EAGAIN || errno == EINTR)
	    continue;
	  fprintf(stderr, "Unhandled signal - exiting...\n");
	  return(-1);
	}

      /* Check if there was a timeout */
      if(ret == 0)
	{
	  unsigned char *	newbuf;

	realloc:
	  /* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
	  newbuf = realloc(buffer, buflen);
	  if(newbuf == NULL)
	    {
	      if(buffer)
		free(buffer);
	      fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
	      return(-1);
	    }
	  buffer = newbuf;

	  /* Try to read the results */
	  wrq.u.data.pointer = buffer;
	  wrq.u.data.flags = 0;
	  wrq.u.data.length = buflen;
	  if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
	    {
	      /* Check if buffer was too small (WE-17 only) */
	      if((errno == E2BIG) && (range.we_version_compiled > 16))
		{
		  /* Some driver may return very large scan results, either
		   * because there are many cells, or because they have many
		   * large elements in cells (like IWEVCUSTOM). Most will
		   * only need the regular sized buffer. We now use a dynamic
		   * allocation of the buffer to satisfy everybody. Of course,
		   * as we don't know in advance the size of the array, we try
		   * various increasing sizes. Jean II */

		  /* Check if the driver gave us any hints. */
		  if(wrq.u.data.length > buflen)
		    buflen = wrq.u.data.length;
		  else
		    buflen *= 2;

		  /* Try again */
		  goto realloc;
		}

	      /* Check if results not available yet */
	      if(errno == EAGAIN)
		{
		  /* Restart timer for only 100ms*/
		  tv.tv_sec = 0;
		  tv.tv_usec = 100000;
		  timeout -= tv.tv_usec;
		  if(timeout > 0)
		    continue;	/* Try again later */
		}

	      /* Bad error */
	      free(buffer);
	      fprintf(stderr, "%-8.16s  Failed to read scan data : %s\n\n",
		      ifname, strerror(errno));
	      return(-2);
	    }
	  else
	    /* We have the results, go to process them */
	    break;
	}

      /* In here, check if event and event type
       * if scan event, read results. All errors bad & no reset timeout */
    }

  if(wrq.u.data.length)
    {
      struct iw_event		iwe;
      struct stream_descr	stream;
      struct iwscan_state	state = { .ap_num = 1, .val_index = 0 };
      int			ret;
      
#if 0
      /* Debugging code. In theory useless, because it's debugged ;-) */
      int	i;
      printf("Scan result %d [%02X", wrq.u.data.length, buffer[0]);
      for(i = 1; i < wrq.u.data.length; i++)
	printf(":%02X", buffer[i]);
      printf("]\n");
#endif
      printf("%-8.16s  Scan completed :\n", ifname);
      iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
      do
	{
	  /* Extract an event and print it */
	  ret = iw_extract_event_stream(&stream, &iwe,
					range.we_version_compiled);
	  if(ret > 0)
	    print_scanning_token(&stream, &iwe, &state,
				 &range, has_range);
	}
      while(ret > 0);
      printf("\n");
    }
  else
    printf("%-8.16s  No scan results\n", ifname);

  free(buffer);
  return(0);
}