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

📄 iwlib.c

📁 iwconfig iwlist iwpriv
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *	Wireless Tools * *		Jean II - HPLB 97->99 - HPL 99->03 * * Common subroutines to all the wireless tools... * * This file is released under the GPL license. *     Copyright (c) 1997-2003 Jean Tourrilhes <jt@hpl.hp.com> *//***************************** INCLUDES *****************************/#include "iwlib.h"		/* Header *//************************ CONSTANTS & MACROS ************************//* Various versions information *//* Recommended Wireless Extension version */#define WE_VERSION	16	/* ### don't forget #warning ### *//* Version of Wireless Tools */#define WT_VERSION	26/* * Verify a few things about Wireless Extensions. * I try to maximise backward and forward compatibility, but things are * tricky because I'm fixing bugs and adding new features. * Wireless Tools *must* be compiled with the same version of WE * as the driver. Sometime, the size or layout of some structure changes, * and might produce interesting results. * Wireless Tools will usually compile properly against different * versions of WE, thanks to the zillions of #ifdefs in my code. * Jean II */#if WIRELESS_EXT < 9#error "Wireless Extension v9 or newer required :-("#error "Use Wireless Tools v19 or update your kernel headers !"#endif#if WIRELESS_EXT < WE_VERSION && !defined(WEXT_HEADER)#warning "Wireless Extension earlier than v16 detected,"#warning "Not all tools features will be compiled in !"#warning "No worry, I'll try to make the best of it ;-)"#endif#if WIRELESS_EXT > WE_VERSION && !defined(WEXT_HEADER)#warning "Wireless Extension later than v16 detected,"#warning "Maybe you should get a more recent version"#warning "of the Wireless Tools package !"#endif/**************************** VARIABLES ****************************/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(end + 2);}/*------------------------------------------------------------------*//* * 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/wireless 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;	  /* 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 ************************//*------------------------------------------------------------------*//* * Get the range information out of the driver */intiw_get_range_info(int		skfd,		  char *	ifname,		  iwrange *	range){  struct iwreq		wrq;  char			buffer[sizeof(iwrange) * 2];	/* Large enough */  /* 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)    return(-1);  /* Copy stuff at the right place, ignore extra */  memcpy((char *) range, buffer, sizeof(iwrange));  /* Lots of people have driver and tools out of sync as far as Wireless   * Extensions are concerned. It's because /usr/include/linux/wireless.h   * and /usr/src/linux/include/linux/wireless.h are different.   * We try to catch this stuff here... */  if(!iw_ignore_version)    {      /* 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((WIRELESS_EXT > 10) && (wrq.u.data.length >= 300))	{#if WIRELESS_EXT > 10	  /* Version verification - for new versions */	  if(range->we_version_compiled != WIRELESS_EXT)	    {	      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 is using version %d.\n", WIRELESS_EXT);	      fprintf(stderr, "Some things may be broken...\n\n");	    }	  /* Driver version verification */	  if(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");	    }#endif /* WIRELESS_EXT > 10 */	}      else	{	  /* Version verification - for old versions */	  if(wrq.u.data.length != sizeof(iwrange))	    {	      fprintf(stderr, "Warning: Driver for device %s has been compiled with an ancient version\n", ifname);	      fprintf(stderr, "of Wireless Extension, while this program is using version %d.\n", WIRELESS_EXT);	      fprintf(stderr, "Some things may be broken...\n\n");	    }	}    }  /* Don't complain twice.   * In theory, the test apply to each individual driver, but usually   * all drivers are compiled from the same kernel, and most often   * problem is the system/glibc headers. */  iw_ignore_version = 1;  /* 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 */  return(0);}/*------------------------------------------------------------------*//* * 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.8s  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((WIRELESS_EXT > 10) && (wrq.u.data.length >= 300))    {#if WIRELESS_EXT > 10      printf("%-8.8s  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);#endif /* WIRELESS_EXT > 10 */    }  else    {#if 0      fprintf(stderr, "%-8.8s  Wireless Extension version too old.\n\n",		      ifname);#endif    }  return(0);}/*------------------------------------------------------------------*//* * Print the WE versions of the tools. */intiw_print_version_info(char *	toolname){  int		skfd;			/* generic raw socket desc.	*/  char		buff[1024];  FILE *	fh;  char *	p;  int		v;  /* 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.8s  Version %d\n", toolname, WT_VERSION);  printf("          Compatible with Wireless Extension v%d or earlier,\n",	 WE_VERSION);  printf("          Currently compiled with Wireless Extension v%d.\n\n",	 WIRELESS_EXT);  /* Check if /proc/net/wireless is available */  fh = fopen(PROC_NET_WIRELESS, "r");  if(fh != NULL)    {      /* Read the first line of buffer */      fgets(buff, sizeof(buff), fh);      /* Check if it's WE-16 or later */      if(strstr(buff, "| WE") != NULL)	{	  /* 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))	    /* That was it ! */	    printf("Kernel    Currently compiled with Wireless Extension v%d.\n\n", v);	}      /* Cleanup */      fclose(fh);    }  /* Version for each device */  iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);  close(skfd);  return 0;}/*------------------------------------------------------------------*//* * Get information about what private ioctls are supported by the driver */intiw_get_priv_info(int		skfd,		 char *		ifname,		 iwprivargs *	priv,		 int		maxpriv){  struct iwreq		wrq;  /* Ask the driver */  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)    return(-1);  /* Return the number of ioctls */  return(wrq.u.data.length);}/*------------------------------------------------------------------*//* * 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,		    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)    {

⌨️ 快捷键说明

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