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

📄 iwlib.c

📁 iwconfig iwlist iwpriv
💻 C
📖 第 1 页 / 共 4 页
字号:
      info->has_freq = 1;      info->freq = iw_freq2float(&(wrq.u.freq));    }  /* 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 < 6) && (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,		    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 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 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;      if(iw_set_ext(skfd, ifname, SIOCSIWENCODE, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",		  errno, strerror(errno));	  ret = -1;	}    }  /* Set ESSID (extended network), if available */  if(info->has_essid)    {      wrq.u.essid.pointer = (caddr_t) info->essid;      wrq.u.essid.length = strlen(info->essid) + 1;      wrq.u.data.flags = info->essid_on;      if(iw_set_ext(skfd, ifname, SIOCSIWESSID, &wrq) < 0)	{	  fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));	  ret = -1;	}    }  /* Set the current mode of operation */  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;	}    }  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 */intiw_protocol_compare(char *	protocol1,		    char *	protocol2){  char *	dot11 = "IEEE 802.11";  char *	dot11_ds = "Dbg";  /* 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))) )    {      char *	sub1 = protocol1 + strlen(dot11);      char *	sub2 = protocol2 + strlen(dot11);      /* Skip optional separator */      if(*sub1 == '-')	sub1++;      if(*sub2 == '-')	sub2++;      /* Check if they are both 2.4 GHz Direct Sequence compatible */      if( (strchr(dot11_ds, *sub1) != NULL) &&	  (strchr(dot11_ds, *sub2) != NULL) )	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(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(char *	buffer,	      double	freq){  if(freq < KILO)    sprintf(buffer, "Channel:%g", freq);  else    {      if(freq >= GIGA)	sprintf(buffer, "Frequency:%gGHz", freq / GIGA);      else	{	  if(freq >= MEGA)	    sprintf(buffer, "Frequency:%gMHz", freq / MEGA);	  else	    sprintf(buffer, "Frequency:%gkHz", freq / KILO);	}    }}/*------------------------------------------------------------------*//* * Convert a frequency to a channel (negative -> error) */intiw_freq_to_channel(double		freq,		   struct iw_range *	range){  double	ref_freq;  int		k;  /* Check if it's a frequency or not already a channel */  if(freq < KILO)    return(-1);  /* We compare the frequencies as double to ignore differences   * in encoding. Slower, but safer... */  for(k = 0; k < range->num_frequency; k++)    {      ref_freq = iw_freq2float(&(range->freq[k]));      if(freq == ref_freq)	return(range->freq[k].i);    }  /* Not found */  return(-2);}/*********************** BITRATE SUBROUTINES ***********************//*------------------------------------------------------------------*//* * Output a bitrate with proper scaling */voidiw_print_bitrate(char *	buffer,		 int	bitrate){  double	rate = bitrate;  if(rate >= GIGA)    sprintf(buffer, "%gGb/s", rate / GIGA);  else    if(rate >= MEGA)      sprintf(buffer, "%gMb/s", rate / MEGA);    else      sprintf(buffer, "%gkb/s", rate / KILO);}/************************ POWER SUBROUTINES *************************//*------------------------------------------------------------------*//* * Convert a value in dBm to a value in milliWatt. */intiw_dbm2mwatt(int	in){#ifdef WE_NOLIBM  /* Version without libm : slower */  int		ip = in / 10;  int		fp = in % 10;  int		k;  double	res = 1.0;  /* Split integral and floating part to avoid accumulating rounding errors */  for(k = 0; k < ip; k++)    res *= 10;  for(k = 0; k < fp; k++)    res *= LOG10_MAGIC;  return((int) res);#else	/* WE_NOLIBM */  /* Version with libm : faster */  return((int) (floor(pow(10.0, (((double) in) / 10.0)))));#endif	/* WE_NOLIBM */}/*------------------------------------------------------------------*//* * Convert a value in milliWatt to a value in dBm. */intiw_mwatt2dbm(int	in){#ifdef WE_NOLIBM  /* Version without libm : slower */  double	fin = (double) in;  int		res = 0;  /* Split integral and floating part to avoid accumulating rounding errors */  while(fin > 10.0)    {      res += 10;      fin /= 10.0;    }  while(fin > 1.000001)	/* Eliminate rounding errors, take ceil */    {      res += 1;      fin /= LOG10_MAGIC;    }  return(res);#else	/* WE_NOLIBM */  /* Version with libm : faster */  return((int) (ceil(10.0 * log10((double) in))));#endif	/* WE_NOLIBM */}/********************** STATISTICS SUBROUTINES **********************//*------------------------------------------------------------------*//* * Read /proc/net/wireless to get the latest statistics */intiw_get_stats(int	skfd,	     char *	ifname,	     iwstats *	stats){#if WIRELESS_EXT > 11  struct iwreq		wrq;  wrq.u.data.pointer = (caddr_t) stats;  wrq.u.data.length = 0;  wrq.u.data.flags = 1;		/* Clear updated flag */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  if(iw_get_ext(skfd, ifname, SIOCGIWSTATS, &wrq) < 0)    return(-1);  return(0);#else /* WIRELESS_EXT > 11 */  FILE *	f = fopen(PROC_NET_WIRELESS, "r");  char		buf[256];  char *	bp;  int		t;  skfd = skfd;	/* Avoid "Unused parameter" warning */  if(f==NULL)    return -1;  /* Loop on all devices */  while(fgets(buf,255,f))    {      bp=buf;      while(*bp&&isspace(*bp))	bp++;      /* Is it the good device ? */      if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')  	{	  /* Skip ethX: */	  bp=strchr(bp,':');	  bp++;	  /* -- status -- */	  bp = strtok(bp, " ");	  sscanf(bp, "%X", &t);	  stats->status = (unsigned short) t;	  /* -- link quality -- */	  bp = strtok(NULL, " ");	  if(strchr(bp,'.') != NULL)	    stats->qual.updated |= 1;	  sscanf(bp, "%d", &t);	  stats->qual.qual = (unsigned char) t;	  /* -- signal level -- */	  bp = strtok(NULL, " ");	  if(strchr(bp,'.') != NULL)	    stats->qual.updated |= 2;	  sscanf(bp, "%d", &t);	  stats->qual.level = (unsigned char) t;	  /* -- noise level -- */	  bp = strtok(NULL, " ");	  if(strchr(bp,'.') != NULL)	    stats->qual.updated += 4;	  sscanf(bp, "%d", &t);	  stats->qual.noise = (unsigned char) t;	  /* -- discarded packets -- */	  bp = strtok(NULL, " ");	  sscanf(bp, "%d", &stats->discard.nwid);	  bp = strtok(NULL, " ");	  sscanf(bp, "%d", &stats->discard.code);	  bp = strtok(NULL, " ");	  sscanf(bp, "%d", &stats->discard.misc);	  fclose(f);	  return 0;  	}    }  fclose(f);  return -1;#endif /* WIRELESS_EXT > 11 */}

⌨️ 快捷键说明

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