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

📄 iwlib.c

📁 This package contains the Wireless tools, used to manipulate the Wireless Extensions. The Wireless
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *	Wireless Tools * *		Jean II - HPLB 97->99 - HPL 99->04 * * Common subroutines to all the wireless tools... * * This file is released under the GPL license. *     Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com> *//***************************** INCLUDES *****************************/#include "iwlib.h"		/* Header *//************************ CONSTANTS & MACROS ************************//* * Constants fof WE-9->15 */#define IW15_MAX_FREQUENCIES	16#define IW15_MAX_BITRATES	8#define IW15_MAX_TXPOWER	8#define IW15_MAX_ENCODING_SIZES	8#define IW15_MAX_SPY		8#define IW15_MAX_AP		8/****************************** TYPES ******************************//* *	Struct iw_range up to WE-15 */struct	iw15_range{	__u32		throughput;	__u32		min_nwid;	__u32		max_nwid;	__u16		num_channels;	__u8		num_frequency;	struct iw_freq	freq[IW15_MAX_FREQUENCIES];	__s32		sensitivity;	struct iw_quality	max_qual;	__u8		num_bitrates;	__s32		bitrate[IW15_MAX_BITRATES];	__s32		min_rts;	__s32		max_rts;	__s32		min_frag;	__s32		max_frag;	__s32		min_pmp;	__s32		max_pmp;	__s32		min_pmt;	__s32		max_pmt;	__u16		pmp_flags;	__u16		pmt_flags;	__u16		pm_capa;	__u16		encoding_size[IW15_MAX_ENCODING_SIZES];	__u8		num_encoding_sizes;	__u8		max_encoding_tokens;	__u16		txpower_capa;	__u8		num_txpower;	__s32		txpower[IW15_MAX_TXPOWER];	__u8		we_version_compiled;	__u8		we_version_source;	__u16		retry_capa;	__u16		retry_flags;	__u16		r_time_flags;	__s32		min_retry;	__s32		max_retry;	__s32		min_r_time;	__s32		max_r_time;	struct iw_quality	avg_qual;};/* * Union for all the versions of iwrange. * Fortunately, I mostly only add fields at the end, and big-bang * reorganisations are few. */union	iw_range_raw{	struct iw15_range	range15;	/* WE 9->15 */	struct iw_range		range;		/* WE 16->current */};/* * Offsets in iw_range struct */#define iwr15_off(f)	( ((char *) &(((struct iw15_range *) NULL)->f)) - \			  (char *) NULL)#define iwr_off(f)	( ((char *) &(((struct iw_range *) NULL)->f)) - \			  (char *) NULL)/**************************** VARIABLES ****************************//* Modes as human readable strings */const char * const iw_operation_mode[] = { "Auto",					"Ad-Hoc",					"Managed",					"Master",					"Repeater",					"Secondary",					"Monitor" };/* Disable runtime version warning in iw_get_range_info() */int	iw_ignore_version = 0;/************************ SOCKET SUBROUTINES *************************//*------------------------------------------------------------------*//* * Open a socket. * Depending on the protocol present, open the right socket. The socket * will allow us to talk to the driver. */intiw_sockets_open(void){  static const int families[] = {    AF_INET, AF_IPX, AF_AX25, AF_APPLETALK  };  unsigned int	i;  int		sock;  /*   * Now pick any (exisiting) useful socket family for generic queries   * Note : don't open all the socket, only returns when one matches,   * all protocols might not be valid.   * Workaround by Jim Kaba <jkaba@sarnoff.com>   * Note : in 99% of the case, we will just open the inet_sock.   * The remaining 1% case are not fully correct...   */  /* Try all families we support */  for(i = 0; i < sizeof(families)/sizeof(int); ++i)    {      /* Try to open the socket, if success returns it */      sock = socket(families[i], SOCK_DGRAM, 0);      if(sock >= 0)	return sock;  }  return -1;}/*------------------------------------------------------------------*//* * Extract the interface name out of /proc/net/wireless or /proc/net/dev. */static inline char *iw_get_ifname(char *	name,	/* Where to store the name */	      int	nsize,	/* Size of name buffer */	      char *	buf)	/* Current position in buffer */{  char *	end;  /* Skip leading spaces */  while(isspace(*buf))    buf++;#ifndef IW_RESTRIC_ENUM  /* Get name up to the last ':'. Aliases may contain ':' in them,   * but the last one should be the separator */  end = strrchr(buf, ':');#else  /* Get name up to ": "   * Note : we compare to ": " to make sure to process aliased interfaces   * properly. Doesn't work on /proc/net/dev, because it doesn't guarantee   * a ' ' after the ':'*/  end = strstr(buf, ": ");#endif  /* Not found ??? To big ??? */  if((end == NULL) || (((end - buf) + 1) > nsize))    return(NULL);  /* Copy */  memcpy(name, buf, (end - buf));  name[end - buf] = '\0';  /* Return value currently unused, just make sure it's non-NULL */  return(end);}/*------------------------------------------------------------------*//* * Enumerate devices and call specified routine * The new way just use /proc/net/wireless, so get all wireless interfaces, * whether configured or not. This is the default if available. * The old way use SIOCGIFCONF, so get only configured interfaces (wireless * or not). */voidiw_enum_devices(int		skfd,		iw_enum_handler	fn,		char *		args[],		int		count){  char		buff[1024];  FILE *	fh;  struct ifconf ifc;  struct ifreq *ifr;  int		i;#ifndef IW_RESTRIC_ENUM  /* Check if /proc/net/dev is available */  fh = fopen(PROC_NET_DEV, "r");#else  /* Check if /proc/net/wireless is available */  fh = fopen(PROC_NET_WIRELESS, "r");#endif  if(fh != NULL)    {      /* Success : use data from /proc/net/wireless */      /* Eat 2 lines of header */      fgets(buff, sizeof(buff), fh);      fgets(buff, sizeof(buff), fh);      /* Read each device line */      while(fgets(buff, sizeof(buff), fh))	{	  char	name[IFNAMSIZ + 1];	  char *s;	  /* Skip empty or almost empty lines. It seems that in some	   * cases fgets return a line with only a newline. */	  if((buff[0] == '\0') || (buff[1] == '\0'))	    continue;	  /* Extract interface name */	  s = iw_get_ifname(name, sizeof(name), buff);	  if(!s)	    {	      /* Failed to parse, complain and continue */#ifndef IW_RESTRIC_ENUM	      fprintf(stderr, "Cannot parse " PROC_NET_DEV "\n");#else	      fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");#endif	    }	  else	    /* Got it, print info about this interface */	    (*fn)(skfd, name, args, count);	}      fclose(fh);    }  else    {      /* Get list of configured devices using "traditional" way */      ifc.ifc_len = sizeof(buff);      ifc.ifc_buf = buff;      if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)	{	  fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));	  return;	}      ifr = ifc.ifc_req;      /* Print them */      for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)	(*fn)(skfd, ifr->ifr_name, args, count);    }}/*********************** WIRELESS SUBROUTINES ************************//*------------------------------------------------------------------*//* * Extract WE version number from /proc/net/wireless * In most cases, you really want to get version information from * the range info (range->we_version_compiled), see below... * * If we have WE-16 and later, the WE version is available at the * end of the header line of the file. * For version prior to that, we can only detect the change from * v11 to v12, so we do an approximate job. Fortunately, v12 to v15 * are highly binary compatible (on the struct level). */intiw_get_kernel_we_version(void){  char		buff[1024];  FILE *	fh;  char *	p;  int		v;  /* Check if /proc/net/wireless is available */  fh = fopen(PROC_NET_WIRELESS, "r");  if(fh == NULL)    {      fprintf(stderr, "Cannot read " PROC_NET_WIRELESS "\n");      return(-1);    }  /* Read the first line of buffer */  fgets(buff, sizeof(buff), fh);  if(strstr(buff, "| WE") == NULL)    {      /* Prior to WE16, so explicit version not present */      /* Black magic */      if(strstr(buff, "| Missed") == NULL)	v = 11;      else	v = 15;      fclose(fh);      return(v);    }  /* Read the second line of buffer */  fgets(buff, sizeof(buff), fh);  /* Get to the last separator, to get the version */  p = strrchr(buff, '|');  if((p == NULL) || (sscanf(p + 1, "%d", &v) != 1))    {      fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n");      fclose(fh);      return(-1);    }  fclose(fh);  return(v);}/*------------------------------------------------------------------*//* * Print the WE versions of the interface. */static intprint_iface_version_info(int	skfd,			 char *	ifname,			 char *	args[],		/* Command line args */			 int	count)		/* Args count */{  struct iwreq		wrq;  char			buffer[sizeof(iwrange) * 2];	/* Large enough */  struct iw_range *	range;  /* Avoid "Unused parameter" warning */  args = args; count = count;  /* If no wireless name : no wireless extensions.   * This enable us to treat the SIOCGIWRANGE failure below properly. */  if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)    return(-1);  /* Cleanup */  memset(buffer, 0, sizeof(buffer));  wrq.u.data.pointer = (caddr_t) buffer;  wrq.u.data.length = sizeof(buffer);  wrq.u.data.flags = 0;  if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)    {      /* Interface support WE (see above), but not IWRANGE */      fprintf(stderr, "%-8.16s  Driver has no Wireless Extension version information.\n\n", ifname);      return(0);    }  /* Copy stuff at the right place, ignore extra */  range = (struct iw_range *) buffer;  /* For new versions, we can check the version directly, for old versions   * we use magic. 300 bytes is a also magic number, don't touch... */  if(wrq.u.data.length >= 300)    {      /* Version is always at the same offset, so it's ok */      printf("%-8.16s  Recommend Wireless Extension v%d or later,\n",	     ifname, range->we_version_source);      printf("          Currently compiled with Wireless Extension v%d.\n\n",	     range->we_version_compiled);    }  else    {      fprintf(stderr, "%-8.16s  Wireless Extension version too old.\n\n",		      ifname);    }  return(0);}/*------------------------------------------------------------------*//* * Print the WE versions of the tools. */intiw_print_version_info(const char *	toolname){  int		skfd;			/* generic raw socket desc.	*/  int		we_kernel_version;  /* Create a channel to the NET kernel. */  if((skfd = iw_sockets_open()) < 0)    {      perror("socket");      return -1;    }  /* Information about the tools themselves */  if(toolname != NULL)    printf("%-8.16s  Wireless-Tools version %d\n", toolname, WT_VERSION);  printf("          Compatible with Wireless Extension v11 to v%d.\n\n",	 WE_VERSION);  /* Get version from kernel */  we_kernel_version = iw_get_kernel_we_version();  /* Only version >= 16 can be verified, other are guessed */  if(we_kernel_version > 15)    printf("Kernel    Currently compiled with Wireless Extension v%d.\n\n",	   we_kernel_version);  /* Version for each device */  iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);  iw_sockets_close(skfd);  return 0;}/*------------------------------------------------------------------*//* * Get the range information out of the driver */intiw_get_range_info(int		skfd,		  const char *	ifname,		  iwrange *	range){  struct iwreq		wrq;  char			buffer[sizeof(iwrange) * 2];	/* Large enough */  union iw_range_raw *	range_raw;  /* Cleanup */  bzero(buffer, sizeof(buffer));  wrq.u.data.pointer = (caddr_t) buffer;  wrq.u.data.length = sizeof(buffer);  wrq.u.data.flags = 0;  if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)    return(-1);  /* Point to the buffer */  range_raw = (union iw_range_raw *) buffer;  /* For new versions, we can check the version directly, for old versions   * we use magic. 300 bytes is a also magic number, don't touch... */  if(wrq.u.data.length < 300)    {      /* That's v10 or earlier. Ouch ! Let's make a guess...*/      range_raw->range.we_version_compiled = 9;    }  /* Check how it needs to be processed */  if(range_raw->range.we_version_compiled > 15)    {      /* This is our native format, that's easy... */      /* Copy stuff at the right place, ignore extra */      memcpy((char *) range, buffer, sizeof(iwrange));    }  else    {      /* Zero unknown fields */      bzero((char *) range, sizeof(struct iw_range));      /* Initial part unmoved */      memcpy((char *) range,	     buffer,	     iwr15_off(num_channels));      /* Frequencies pushed futher down towards the end */      memcpy((char *) range + iwr_off(num_channels),	     buffer + iwr15_off(num_channels),	     iwr15_off(sensitivity) - iwr15_off(num_channels));      /* This one moved up */      memcpy((char *) range + iwr_off(sensitivity),	     buffer + iwr15_off(sensitivity),	     iwr15_off(num_bitrates) - iwr15_off(sensitivity));      /* This one goes after avg_qual */      memcpy((char *) range + iwr_off(num_bitrates),	     buffer + iwr15_off(num_bitrates),	     iwr15_off(min_rts) - iwr15_off(num_bitrates));      /* Number of bitrates has changed, put it after */      memcpy((char *) range + iwr_off(min_rts),	     buffer + iwr15_off(min_rts),	     iwr15_off(txpower_capa) - iwr15_off(min_rts));      /* Added encoding_login_index, put it after */      memcpy((char *) range + iwr_off(txpower_capa),	     buffer + iwr15_off(txpower_capa),

⌨️ 快捷键说明

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