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

📄 iwgetid.c

📁 iwconfig iwlist iwpriv
💻 C
字号:
/* *	Wireless Tools * *		Jean II - HPL '01 * * Just print the ESSID or NWID... * * This file is released under the GPL license. *     Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com> */#include "iwlib.h"		/* Header */#include <getopt.h>#define FORMAT_DEFAULT	0	/* Nice looking display for the user */#define FORMAT_SCHEME	1	/* To be used as a Pcmcia Scheme */#define WTYPE_ESSID	0	/* Display ESSID or NWID */#define WTYPE_AP	1	/* Display AP/Cell Address */#define WTYPE_FREQ	2	/* Display frequency/channel */#define WTYPE_MODE	3	/* Display mode */#define WTYPE_PROTO	4	/* Display protocol name *//* * Note on Pcmcia Schemes : * ---------------------- *	The purpose of this tool is to use the ESSID discovery mechanism * to select the appropriate Pcmcia Scheme. The card tell us which * ESSID it has found, and we can then select the appropriate Pcmcia * Scheme for this ESSID (Wireless config (encrypt keys) and IP config). *	The way to do it is as follows : *			cardctl scheme "essidany" *			delay 100 *			$scheme = iwgetid --scheme *			cardctl scheme $scheme *	Of course, you need to add a scheme called "essidany" with the * following setting : *			essidany,*,*,*) *				ESSID="any" *				IPADDR="10.0.0.1" * *	This can also be integrated int he Pcmcia scripts. *	Some drivers don't activate the card up to "ifconfig up". * Therefore, they wont scan ESSID up to this point, so we can't * read it reliably in Pcmcia scripts. *	I guess the proper way to write the network script is as follows : *			if($scheme == "iwgetid") { *				iwconfig $name essid any *				iwconfig $name nwid any *				ifconfig $name up *				delay 100 *				$scheme = iwgetid $name --scheme *				ifconfig $name down *			} * *	This is pseudo code, but you get an idea... *	The "ifconfig up" activate the card. *	The "delay" is necessary to let time for the card scan the * frequencies and associate with the AP. *	The "ifconfig down" is necessary to allow the driver to optimise * the wireless parameters setting (minimise number of card resets). * *	Another cute idea is to have a list of Pcmcia Schemes to try * and to keep the first one that associate (AP address != 0). This * would be necessary for closed networks and cards that can't * discover essid... * * Jean II - 29/3/01 *//*************************** SUBROUTINES ***************************//* * Just for the heck of it, let's try to not link with iwlib. * This will keep the binary small and tiny... * * Note : maybe it's time to admit that we have lost the battle * and we start using iwlib ? Maybe we should default to dynamic * lib first... *//*------------------------------------------------------------------*//* * 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){        int ipx_sock = -1;              /* IPX socket                   */        int ax25_sock = -1;             /* AX.25 socket                 */        int inet_sock = -1;             /* INET socket                  */        int ddp_sock = -1;              /* Appletalk DDP socket         */        /*         * 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...         */        inet_sock=socket(AF_INET, SOCK_DGRAM, 0);        if(inet_sock!=-1)                return inet_sock;        ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);        if(ipx_sock!=-1)                return ipx_sock;        ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);        if(ax25_sock!=-1)                return ax25_sock;        ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);        /*         * If this is -1 we have no known network layers and its time to jump.         */        return ddp_sock;}/*------------------------------------------------------------------*//* * Display an Ethernet address in readable format. */voidiw_ether_ntop(const struct ether_addr* eth, char* buf){  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",	  eth->ether_addr_octet[0], eth->ether_addr_octet[1],	  eth->ether_addr_octet[2], eth->ether_addr_octet[3],	  eth->ether_addr_octet[4], eth->ether_addr_octet[5]);}/*------------------------------------------------------------------*//* * 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);	}    }}/*------------------------------------------------------------------*/const char * const iw_operation_mode[] = { "Auto",					"Ad-Hoc",					"Managed",					"Master",					"Repeater",					"Secondary",					"Monitor" };/************************ DISPLAY ESSID/NWID ************************//*------------------------------------------------------------------*//* * Display the ESSID if possible */static intprint_essid(int			skfd,	    const char *	ifname,	    int			format){  struct iwreq		wrq;  char			essid[IW_ESSID_MAX_SIZE + 1];	/* ESSID */  char			pessid[IW_ESSID_MAX_SIZE + 1];	/* Pcmcia format */  unsigned int		i;  unsigned int		j;  /* Get ESSID */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  wrq.u.essid.pointer = (caddr_t) essid;  wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;  wrq.u.essid.flags = 0;  if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)    return(-1);  switch(format)    {    case FORMAT_SCHEME:      /* Strip all white space and stuff */      j = 0;      for(i = 0; i < strlen(essid); i++)	if(isalnum(essid[i]))	  pessid[j++] = essid[i];      pessid[j] = '\0';      if((j == 0) || (j > 32))	return(-2);      printf("%s\n", pessid);      break;    default:      printf("%-8.8s  ESSID:\"%s\"\n", ifname, essid);      break;    }  return(0);}/*------------------------------------------------------------------*//* * Display the NWID if possible */static intprint_nwid(int		skfd,	   const char *	ifname,	   int		format){  struct iwreq		wrq;  /* Get network ID */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)    return(-1);  switch(format)    {    case FORMAT_SCHEME:      /* Prefix with nwid to avoid name space collisions */      printf("nwid%X\n", wrq.u.nwid.value);      break;    default:      printf("%-8.8s  NWID:%X\n", ifname, wrq.u.nwid.value);      break;    }  return(0);}/**************************** AP ADDRESS ****************************//*------------------------------------------------------------------*//* * Display the AP Address if possible */static intprint_ap(int		skfd,	 const char *	ifname,	 int		format){  struct iwreq		wrq;  char			buffer[64];  /* Get AP Address */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)    return(-1);  /* Print */  iw_ether_ntop((const struct ether_addr *) wrq.u.ap_addr.sa_data, buffer);  switch(format)    {    case FORMAT_SCHEME:      /* I think ':' are not problematic, because Pcmcia scripts       * seem to handle them properly... */      printf("%s\n", buffer);      break;    default:      printf("%-8.8s  Access Point/Cell: %s\n", ifname, buffer);      break;    }  return(0);}/****************************** OTHER ******************************//*------------------------------------------------------------------*//* * Display the frequency (or channel) if possible */static intprint_freq(int		skfd,	   const char *	ifname,	   int		format){  struct iwreq		wrq;  double		freq;  char			buffer[64];  /* Get frequency / channel */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  if(ioctl(skfd, SIOCGIWFREQ, &wrq) < 0)    return(-1);  /* Print */  freq = iw_freq2float(&(wrq.u.freq));  switch(format)    {    case FORMAT_SCHEME:      printf("%g\n", freq);      break;    default:      iw_print_freq(buffer, freq);      printf("%-8.8s  %s\n", ifname, buffer);      break;    }  return(0);}/*------------------------------------------------------------------*//* * Display the mode if possible */static intprint_mode(int		skfd,	   const char *	ifname,	   int		format){  struct iwreq		wrq;  /* Get frequency / channel */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  if(ioctl(skfd, SIOCGIWMODE, &wrq) < 0)    return(-1);  if(wrq.u.mode >= IW_NUM_OPER_MODE)    return(-2);  /* Print */  switch(format)    {    case FORMAT_SCHEME:      printf("%d\n", wrq.u.mode);      break;    default:      printf("%-8.8s  Mode:%s\n", ifname, iw_operation_mode[wrq.u.mode]);      break;    }  return(0);}/*------------------------------------------------------------------*//* * Display the ESSID if possible */static intprint_protocol(int		skfd,	       const char *	ifname,	       int		format){  struct iwreq		wrq;  char			proto[IFNAMSIZ + 1];	/* Protocol */  char			pproto[IFNAMSIZ + 1];	/* Pcmcia format */  unsigned int		i;  unsigned int		j;  /* Get Protocol name */  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);  if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)    return(-1);  strncpy(proto, wrq.u.name, IFNAMSIZ);  proto[IFNAMSIZ] = '\0';  switch(format)    {    case FORMAT_SCHEME:      /* Strip all white space and stuff */      j = 0;      for(i = 0; i < strlen(proto); i++)	if(isalnum(proto[i]))	  pproto[j++] = proto[i];      pproto[j] = '\0';      if((j == 0) || (j > 32))	return(-2);      printf("%s\n", pproto);      break;    default:      printf("%-8.8s  Protocol Name:\"%s\"\n", ifname, proto);      break;    }  return(0);}/******************************* MAIN ********************************//*------------------------------------------------------------------*//* * Check options and call the proper handler */static intprint_one_device(int		skfd,		 int		format,		 int		wtype,		 const char*	ifname){  int ret;  /* Check wtype */  switch(wtype)    {    case WTYPE_AP:      /* Try to print an AP */      ret = print_ap(skfd, ifname, format);      break;    case WTYPE_FREQ:      /* Try to print frequency */      ret = print_freq(skfd, ifname, format);      break;    case WTYPE_MODE:      /* Try to print the mode */      ret = print_mode(skfd, ifname, format);      break;    case WTYPE_PROTO:      /* Try to print the protocol */      ret = print_protocol(skfd, ifname, format);      break;    default:      /* Try to print an ESSID */      ret = print_essid(skfd, ifname, format);      if(ret < 0)	{	  /* Try to print a nwid */	  ret = print_nwid(skfd, ifname, format);	}    }  return(ret);}/*------------------------------------------------------------------*//* * Try the various devices until one return something we can use */static intscan_devices(int		skfd,	     int		format,	     int		wtype){  char		buff[1024];  struct ifconf ifc;  struct ifreq *ifr;  int		i;  /* Get list of active devices */  ifc.ifc_len = sizeof(buff);  ifc.ifc_buf = buff;  if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)    {      perror("SIOCGIFCONF");      return(-1);    }  ifr = ifc.ifc_req;  /* Print the first match */  for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)    {      if(print_one_device(skfd, format, wtype, ifr->ifr_name) >= 0)	return 0;    }  return(-1);}/*------------------------------------------------------------------*//* * helper */static voidiw_usage(int status){  fputs("Usage iwgetid [OPTIONS] [ifname]\n"	"  Options are:\n"	"    -a,--ap       Print the access point address\n"	"    -f,--freq     Print the current frequency\n"	"    -m,--mode     Print the current mode\n"	"    -p,--protocol Print the protocol name\n"	"    -s,--scheme   Format the output as a PCMCIA scheme identifier\n"	"    -h,--help     Print this message\n",	status ? stderr : stdout);  exit(status);}static const struct option long_opts[] = {  { "ap", no_argument, NULL, 'a' },  { "freq", no_argument, NULL, 'f' },  { "mode", no_argument, NULL, 'm' },  { "protocol", no_argument, NULL, 'p' },  { "help", no_argument, NULL, 'h' },  { "scheme", no_argument, NULL, 's' },  { NULL, 0, NULL, 0 }};/*------------------------------------------------------------------*//* * The main ! */intmain(int	argc,     char **	argv){  int	skfd;			/* generic raw socket desc.	*/  int	format = FORMAT_DEFAULT;  int	wtype = WTYPE_ESSID;  int	opt;  int	ret = -1;  /* Check command line arguments */  while((opt = getopt_long(argc, argv, "afhmps", long_opts, NULL)) > 0)    {      switch(opt)	{	case 'a':	  /* User wants AP/Cell Address */	  wtype = WTYPE_AP;	  break;	case 'f':	  /* User wants frequency/channel */	  wtype = WTYPE_FREQ;	  break;	case 'm':	  /* User wants the mode */	  wtype = WTYPE_MODE;	  break;	case 'p':	  /* User wants the protocol */	  wtype = WTYPE_PROTO;	  break;	case 'h':	  iw_usage(0);	  break;	case 's':	  /* User wants a Scheme format */	  format = FORMAT_SCHEME;	  break;	default:	  iw_usage(1);	  break;	}    }  if(optind + 1 < argc) {    fputs("Too many arguments.\n", stderr);    iw_usage(1);  }  /* Create a channel to the NET kernel. */  if((skfd = iw_sockets_open()) < 0)    {      perror("socket");      return(-1);    }  /* Check if first argument is a device name */  if(optind < argc)    {      /* Yes : query only this device */      ret = print_one_device(skfd, format, wtype, argv[optind]);    }  else    {      /* No : query all devices and print first found */      ret = scan_devices(skfd, format, wtype);    }  fflush(stdout);  close(skfd);  return(ret);}

⌨️ 快捷键说明

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