⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iwlib.c

📁 This package contains the Wireless tools, used to manipulate the Wireless Extensions. The Wireless
💻 C
📖 第 1 页 / 共 5 页
字号:
	     iwr15_off(txpower) - iwr15_off(txpower_capa));      /* Hum... That's an unexpected glitch. Bummer. */      memcpy((char *) range + iwr_off(txpower),	     buffer + iwr15_off(txpower),	     iwr15_off(avg_qual) - iwr15_off(txpower));      /* Avg qual moved up next to max_qual */      memcpy((char *) range + iwr_off(avg_qual),	     buffer + iwr15_off(avg_qual),	     sizeof(struct iw_quality));    }  /* We are now checking much less than we used to do, because we can   * accomodate more WE version. But, there are still cases where things   * will break... */  if(!iw_ignore_version)    {      /* We don't like very old version (unfortunately kernel 2.2.X) */      if(range->we_version_compiled <= 10)	{	  fprintf(stderr, "Warning: Driver for device %s has been compiled with an ancient version\n", ifname);	  fprintf(stderr, "of Wireless Extension, while this program support version 11 and later.\n");	  fprintf(stderr, "Some things may be broken...\n\n");	}      /* We don't like future versions of WE, because we can't cope with       * the unknown */      if(range->we_version_compiled > WE_MAX_VERSION)	{	  fprintf(stderr, "Warning: Driver for device %s has been compiled with version %d\n", ifname, range->we_version_compiled);	  fprintf(stderr, "of Wireless Extension, while this program supports up to version %d.\n", WE_VERSION);	  fprintf(stderr, "Some things may be broken...\n\n");	}      /* Driver version verification */      if((range->we_version_compiled > 10) &&	 (range->we_version_compiled < range->we_version_source))	{	  fprintf(stderr, "Warning: Driver for device %s recommend version %d of Wireless Extension,\n", ifname, range->we_version_source);	  fprintf(stderr, "but has been compiled with version %d, therefore some driver features\n", range->we_version_compiled);	  fprintf(stderr, "may not be available...\n\n");	}      /* Note : we are only trying to catch compile difference, not source.       * If the driver source has not been updated to the latest, it doesn't       * matter because the new fields are set to zero */    }  /* Don't complain twice.   * In theory, the test apply to each individual driver, but usually   * all drivers are compiled from the same kernel. */  iw_ignore_version = 1;  return(0);}/*------------------------------------------------------------------*//* * Get information about what private ioctls are supported by the driver * * Note : there is one danger using this function. If it return 0, you * still need to free() the buffer. Beware. */intiw_get_priv_info(int		skfd,		 const char *	ifname,		 iwprivargs **	ppriv){  struct iwreq		wrq;  iwprivargs *		priv = NULL;	/* Not allocated yet */  int			maxpriv = 16;	/* Minimum for compatibility WE<13 */  iwprivargs *		newpriv;  /* Some driver may return a very large number of ioctls. Some   * others a very small number. We now use a dynamic allocation   * of the array to satisfy everybody. Of course, as we don't know   * in advance the size of the array, we try various increasing   * sizes. Jean II */  do    {      /* (Re)allocate the buffer */      newpriv = realloc(priv, maxpriv * sizeof(priv[0]));      if(newpriv == NULL)	{	  fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);	  break;	}      priv = newpriv;      /* Ask the driver if it's large enough */      wrq.u.data.pointer = (caddr_t) priv;      wrq.u.data.length = maxpriv;      wrq.u.data.flags = 0;      if(iw_get_ext(skfd, ifname, SIOCGIWPRIV, &wrq) >= 0)	{	  /* Success. Pass the buffer by pointer */	  *ppriv = priv;	  /* Return the number of ioctls */	  return(wrq.u.data.length);	}      /* Only E2BIG means the buffer was too small, abort on other errors */      if(errno != E2BIG)	{	  /* Most likely "not supported". Don't barf. */	  break;	}      /* Failed. We probably need a bigger buffer. Check if the kernel       * gave us any hints. */      if(wrq.u.data.length > maxpriv)	maxpriv = wrq.u.data.length;      else	maxpriv *= 2;    }  while(maxpriv < 1000);  /* Cleanup */  if(priv)    free(priv);  *ppriv = NULL;  return(-1);}/*------------------------------------------------------------------*//* * Get essential wireless 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... * Note : compare to the version in iwconfig, we extract only * what's *really* needed to configure a device... */intiw_get_basic_config(int			skfd,		    const char *	ifname,		    wireless_config *	info){  struct iwreq		wrq;  memset((char *) info, 0, sizeof(struct wireless_config));  /* Get wireless name */  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)    /* If no wireless name : no wireless extensions */    return(-1);  else    {      strncpy(info->name, wrq.u.name, IFNAMSIZ);      info->name[IFNAMSIZ] = '\0';    }  /* 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));      info->freq_flags = wrq.u.freq.flags;    }  /* 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 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;    }  return(0);}/*------------------------------------------------------------------*//* * Set essential wireless config in the device driver * We will call all the classical wireless ioctl on the driver through * the socket to know what is supported and to set the settings... * We support only the restricted set as above... */intiw_set_basic_config(int			skfd,		    const char *	ifname,		    wireless_config *	info){  struct iwreq		wrq;  int			ret = 0;  /* Get wireless name (check if interface is valid) */  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)    /* If no wireless name : no wireless extensions */    return(-2);  /* Set the current mode of operation   * Mode need to be first : some settings apply only in a specific mode   * (such as frequency).   */  if(info->has_mode)    {      strncpy(wrq.ifr_name, ifname, IFNAMSIZ);      wrq.u.mode = info->mode;      if(iw_get_ext(skfd, ifname, SIOCSIWMODE, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));	  ret = -1;	}    }  /* Set frequency / channel */  if(info->has_freq)    {      iw_float2freq(info->freq, &(wrq.u.freq));      if(iw_set_ext(skfd, ifname, SIOCSIWFREQ, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));	  ret = -1;	}    }  /* Set encryption information */  if(info->has_key)    {      int		flags = info->key_flags;      /* Check if there is a key index */      if((flags & IW_ENCODE_INDEX) > 0)	{	  /* Set the index */	  wrq.u.data.pointer = (caddr_t) NULL;	  wrq.u.data.flags = (flags & (IW_ENCODE_INDEX)) | IW_ENCODE_NOKEY;	  wrq.u.data.length = 0;	  if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0)	    {	      fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",		      errno, strerror(errno));	      ret = -1;	    }	}      /* Mask out index to minimise probability of reject when setting key */      flags = flags & (~IW_ENCODE_INDEX);      /* Set the key itself (set current key in this case) */      wrq.u.data.pointer = (caddr_t) info->key;      wrq.u.data.length = info->key_size;      wrq.u.data.flags = flags;      /* Compatibility with WE<13 */      if(flags & IW_ENCODE_NOKEY)	wrq.u.data.pointer = NULL;      if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",		  errno, strerror(errno));	  ret = -1;	}    }  /* Set Network ID, if available (this is for non-802.11 cards) */  if(info->has_nwid)    {      memcpy(&(wrq.u.nwid), &(info->nwid), sizeof(iwparam));      wrq.u.nwid.fixed = 1;	/* Hum... When in Rome... */      if(iw_set_ext(skfd, ifname, SIOCSIWNWID, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));	  ret = -1;	}    }  /* Set ESSID (extended network), if available.   * ESSID need to be last : most device re-perform the scanning/discovery   * when this is set, and things like encryption keys are better be   * defined if we want to discover the right set of APs/nodes.   */  if(info->has_essid)    {      int		we_kernel_version;      we_kernel_version = iw_get_kernel_we_version();      wrq.u.essid.pointer = (caddr_t) info->essid;      wrq.u.essid.length = strlen(info->essid) + 1;      wrq.u.data.flags = info->essid_on;      if(we_kernel_version > 20)	wrq.u.essid.length--;      if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));	  ret = -1;	}    }  return(ret);}/*********************** PROTOCOL SUBROUTINES ***********************//* * Fun stuff with protocol identifiers (SIOCGIWNAME). * We assume that drivers are returning sensible values in there, * which is not always the case :-( *//*------------------------------------------------------------------*//* * Compare protocol identifiers. * We don't want to know if the two protocols are the exactly same, * but if they interoperate at some level, and also if they accept the * same type of config (ESSID vs NWID, freq...). * This is supposed to work around the alphabet soup. * Return 1 if protocols are compatible, 0 otherwise */intiw_protocol_compare(const char *	protocol1,		    const char *	protocol2){  const char *	dot11 = "IEEE 802.11";  const char *	dot11_ds = "Dbg";  const char *	dot11_5g = "a";  /* If the strings are the same -> easy */  if(!strncmp(protocol1, protocol2, IFNAMSIZ))    return(1);  /* Are we dealing with one of the 802.11 variant ? */  if( (!strncmp(protocol1, dot11, strlen(dot11))) &&      (!strncmp(protocol2, dot11, strlen(dot11))) )    {      const char *	sub1 = protocol1 + strlen(dot11);      const char *	sub2 = protocol2 + strlen(dot11);      unsigned int	i;      int		isds1 = 0;      int		isds2 = 0;      int		is5g1 = 0;      int		is5g2 = 0;      /* Check if we find the magic letters telling it's DS compatible */      for(i = 0; i < strlen(dot11_ds); i++)	{	  if(strchr(sub1, dot11_ds[i]) != NULL)	    isds1 = 1;	  if(strchr(sub2, dot11_ds[i]) != NULL)	    isds2 = 1;	}      if(isds1 && isds2)	return(1);      /* Check if we find the magic letters telling it's 5GHz compatible */      for(i = 0; i < strlen(dot11_5g); i++)	{	  if(strchr(sub1, dot11_5g[i]) != NULL)	    is5g1 = 1;	  if(strchr(sub2, dot11_5g[i]) != NULL)	    is5g2 = 1;	}      if(is5g1 && is5g2)	return(1);    }  /* Not compatible */  return(0);}/********************** FREQUENCY SUBROUTINES ***********************//* * Note : the two functions below are the cause of troubles on * various embeeded platforms, as they are the reason we require * libm (math library). * In this case, please use enable BUILD_NOLIBM in the makefile * * FIXME : check negative mantissa and exponent *//*------------------------------------------------------------------*//* * Convert a floating point the our internal representation of * frequencies. * The kernel doesn't want to hear about floating point, so we use * this custom format instead. */voidiw_float2freq(double	in,	      iwfreq *	out){#ifdef WE_NOLIBM  /* Version without libm : slower */  out->e = 0;  while(in > 1e9)    {      in /= 10;      out->e++;    }  out->m = (long) in;#else	/* WE_NOLIBM */  /* Version with libm : faster */  out->e = (short) (floor(log10(in)));  if(out->e > 8)    {      out->m = ((long) (floor(in / pow(10,out->e - 6)))) * 100;      out->e -= 8;    }  else    {      out->m = (long) in;      out->e = 0;    }#endif	/* WE_NOLIBM */}/*------------------------------------------------------------------*//* * Convert our internal representation of frequencies to a floating point. */doubleiw_freq2float(const iwfreq *	in){#ifdef WE_NOLIBM  /* Version without libm : slower */  int		i;  double	res = (double) in->m;  for(i = 0; i < in->e; i++)    res *= 10;  return(res);#else	/* WE_NOLIBM */  /* Version with libm : faster */  return ((double) in->m) * pow(10,in->e);#endif	/* WE_NOLIBM */}/*------------------------------------------------------------------*//* * Output a frequency with proper scaling */voidiw_print_freq_value(char *	buffer,		    int		buflen,		    double	freq){  if(freq < KILO)    snprintf(buffer, buflen, "%g", freq);  else    {      char	scale;      int	divisor;      if(freq >= GIGA)	{	  scale = 'G';	  divisor = GIGA;	}      else	{	  if(freq >= MEGA)	    {	      scale = 'M';	      divisor = MEGA;	    }	  else	    {	      scale = 'k';	      divisor = KILO;	    }	}      snprintf(buffer, buflen, "%g %cHz", freq / divisor, scale);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -