C_RESULT vp_com_wf_get_rssi(vp_com_wifi_config_t* cfg, int32_t* rssi)
{
#ifdef USE_IWLIB
  struct iwreq wrq;
  iwstats stats;
  iwrange range;

  int wlsock = iw_sockets_open();

  vp_os_memset(&wrq, 0, sizeof(struct iwreq));
  iw_get_stats(wlsock, cfg->itfName, &stats, &range, 1);
  iw_sockets_close(wlsock);

//   struct  iw_statistics
//   {
//     __u16           status;           // Status * - device dependent for now
//     struct iw_quality       qual;     // Quality of the link * (instant/mean/max)
//     struct iw_discarded     discard;  // Packet discarded counts
//     struct iw_missed        miss;     // Packet missed counts
//   };
//
//   struct iw_range
//   {
//     ...
//     //  Quality of link & SNR stuff */
//     //  Quality range (link, level, noise)
//     //  If the quality is absolute, it will be in the range [0 ; max_qual],
//     //  if the quality is dBm, it will be in the range [max_qual ; 0].
//     //  Don't forget that we use 8 bit arithmetics...
//     struct iw_quality       max_qual;       // Quality of the link
//     //  This should contain the average/typical values of the quality
//     //  indicator. This should be the threshold between a "good" and
//     //  a "bad" link (example : monitor going from green to orange).
//     //  Currently, user space apps like quality monitors don't have any
//     //  way to calibrate the measurement. With this, they can split
//     //  the range between 0 and max_qual in different quality level
//     //  (using a geometric subdivision centered on the average).
//     //  I expect that people doing the user space apps will feedback
//     //  us on which value we need to put in each driver...
//     struct iw_quality       avg_qual;       // Quality of the link
//     ...
//   };
//   struct  iw_quality
//   {
//     __u8            qual;           // link quality (%retries, SNR, %missed beacons or better...)
//     __u8            level;          // signal level (dBm)
//     __u8            noise;          // noise level (dBm)
//     __u8            updated;        // Flags to know if updated
//   };

  *rssi = stats.qual.qual;

#endif
  return VP_COM_OK;
}
Example #2
0
static double
get_stats_discarded_nwid(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) {
		return DNAN;
	}

	return (double) stats.discard.nwid;
}
Example #3
0
/* ------------------------------------------------------------------- WirelessInterface_refresh */
static void WirelessInterface_refresh(wiface* self)
{
	iwreq wrq;

	iw_get_basic_config(self->sock, self->ifname, &(self->info.b));
	iw_get_range_info(self->sock, self->ifname, &(self->info.range));

	iw_get_ext(self->sock, self->ifname, SIOCGIWRATE, &wrq);
	memcpy(&(self->info.bitrate), &wrq.u.bitrate, sizeof(iwparam));

	iw_get_ext(self->sock, self->ifname, SIOCGIWAP, &wrq);
	memcpy(&(self->info.ap_addr), &wrq.u.ap_addr, sizeof(sockaddr));

	iw_get_stats(self->sock, self->ifname, &(self->info.stats),
		     &(self->info.range), self->info.has_range);
}
Example #4
0
  /**
  * @brief Gets the signal quality property of the wifi device
  * @return An updated wifi_signal type
  */
  wifi_signal getSignal()
  {
    if (iw_get_stats(wifi_skfd, wifi_dev, &(wifi_info->stats), &wifi_info->range, wifi_info->has_range) >= 0)
      wifi_info->has_stats = 1;
    int quality = wifi_info->stats.qual.qual;
    // Get bit rate
    if (iw_get_ext(wifi_skfd, wifi_dev, SIOCGIWRATE, &wifi_wrq) >= 0)
    {
      wifi_info->has_bitrate = 1;
      memcpy(&(wifi_info->bitrate), &(wifi_wrq.u.bitrate), sizeof(wifi_info->bitrate));
    }

    wifi_sig.link_quality = quality;

    return wifi_sig;
  }
Example #5
0
static double
get_stats_quality_quality(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_quality: UNKNOWN");
		return DNAN;
	}

	xsg_debug("get_stats_quality_quality: %f", (double) stats.qual.qual);
	return (double) stats.qual.qual;
}
Example #6
0
void
get_wireless_info (DevInfo *devinfo)
{
	int fd;
	int newqual;
	wireless_info info = {0};

	fd = iw_sockets_open ();

	if (fd < 0)
		return;

	if (iw_get_basic_config (fd, devinfo->name, &info.b) < 0)
		goto out;

	if (info.b.has_essid) {
		if ((!devinfo->essid) || (strcmp (devinfo->essid, info.b.essid) != 0)) {
			devinfo->essid = g_strdup (info.b.essid);
		}
	} else {
		devinfo->essid = NULL;
	}

	if (iw_get_stats (fd, devinfo->name, &info.stats, &info.range, info.has_range) >= 0)
		info.has_stats = 1;

	if (info.has_stats) {
		if ((iw_get_range_info(fd, devinfo->name, &info.range) >= 0) && (info.range.max_qual.qual > 0)) {
			newqual = 0.5f + (100.0f * info.stats.qual.qual) / (1.0f * info.range.max_qual.qual);
		} else {
			newqual = info.stats.qual.qual;
		}

		newqual = CLAMP(newqual, 0, 100);
		if (devinfo->qual != newqual)
			devinfo->qual = newqual;

	} else {
		devinfo->qual = 0;
	}

	goto out;
out:
	if (fd != -1)
		close (fd);
}
Example #7
0
static double
get_stats_discarded_misc(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_misc: UNKNOWN");
		return DNAN;
	}

	xsg_debug("get_stats_discarded_misc: %f",
			(double) stats.discard.misc);
	return (double) stats.discard.misc;
}
Example #8
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;
}
Example #9
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;
}
Example #10
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;
}
Example #11
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;
}
Example #12
0
/* 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);
	}
}
Example #13
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;
}
Example #14
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);
}
Example #15
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);
}
Example #16
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);
}
Example #17
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;
}