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

📄 iwlist.c

📁 访问网卡的各种信息
💻 C
📖 第 1 页 / 共 4 页
字号:
  wrq.u.data.flags = 0;
  wrq.u.data.length = 0;

  /* Initiate Scanning */
  if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0)
    {
      if(errno != EPERM)
        {
          fprintf(stderr, "%-8.16s  Interface doesn't support scanning : %s\n\n",
                  ifname, strerror(errno));
          return(-1);
        }
      /* If we don't have the permission to initiate the scan, we may
       * still have permission to read left-over results.
       * But, don't wait !!! */
#if 0
      /* Not cool, it display for non wireless interfaces... */
      fprintf(stderr, "%-8.16s  (Could not trigger scanning, just reading left-over results)\n", ifname);
#endif
      tv.tv_usec = 0;
    }
  timeout -= tv.tv_usec;

  /* Forever */
  while(1)
    {
      fd_set		rfds;		/* File descriptors for select */
      int		last_fd;	/* Last fd */
      int		ret;

      /* Guess what ? We must re-generate rfds each time */
      FD_ZERO(&rfds);
      last_fd = -1;

      /* In here, add the rtnetlink fd in the list */

      /* Wait until something happens */
      ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);

      /* Check if there was an error */
      if(ret < 0)
        {
          if(errno == EAGAIN || errno == EINTR)
            continue;
          fprintf(stderr, "Unhandled signal - exiting...\n");
          return(-1);
        }

      /* Check if there was a timeout */
      if(ret == 0)
        {
          unsigned char *	newbuf;

        realloc:
          /* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */
          newbuf = realloc(buffer, buflen);
          if(newbuf == NULL)
            {
              if(buffer)
                free(buffer);
              fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);
              return(-1);
            }
          buffer = newbuf;

          /* Try to read the results */
          wrq.u.data.pointer = buffer;
          wrq.u.data.flags = 0;
          wrq.u.data.length = buflen;
          if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0)
            {
              /* Check if buffer was too small (WE-17 only) */
              if((errno == E2BIG) && (range.we_version_compiled > 16))
                {
                  /* Some driver may return very large scan results, either
                   * because there are many cells, or because they have many
                   * large elements in cells (like IWEVCUSTOM). Most will
                   * only need the regular sized buffer. We now use a dynamic
                   * allocation of the buffer to satisfy everybody. Of course,
                   * as we don't know in advance the size of the array, we try
                   * various increasing sizes. Jean II */

                  /* Check if the driver gave us any hints. */
                  if(wrq.u.data.length > buflen)
                    buflen = wrq.u.data.length;
                  else
                    buflen *= 2;

                  /* Try again */
                  goto realloc;
                }

              /* Check if results not available yet */
              if(errno == EAGAIN)
                {
                  /* Restart timer for only 100ms*/
                  tv.tv_sec = 0;
                  tv.tv_usec = 100000;
                  timeout -= tv.tv_usec;
                  if(timeout > 0)
                    continue;	/* Try again later */
                }

              /* Bad error */
              free(buffer);
              fprintf(stderr, "%-8.16s  Failed to read scan data : %s\n\n",
                      ifname, strerror(errno));
              return(-2);
            }
          else
            /* We have the results, go to process them */
            break;
        }

      /* In here, check if event and event type
       * if scan event, read results. All errors bad & no reset timeout */
    }

  if(wrq.u.data.length)
    {
      struct iw_event		iwe;
      struct stream_descr	stream;
      struct iwscan_state	state = { .ap_num = 1, .val_index = 0 };
      int			ret;
      
#if 0
      /* Debugging code. In theory useless, because it's debugged ;-) */
      int	i;
      printf("Scan result %d [%02X", wrq.u.data.length, buffer[0]);
      for(i = 1; i < wrq.u.data.length; i++)
        printf(":%02X", buffer[i]);
      printf("]\n");
#endif
      printf("%-8.16s  Scan completed :\n", ifname);
      iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
      do
        {
          /* Extract an event and print it */
          ret = iw_extract_event_stream(&stream, &iwe,
                                        range.we_version_compiled);
          if(ret > 0)
            print_scanning_token(&stream, &iwe, &state,
                                 &range, has_range);
        }
      while(ret > 0);
      printf("\n");
    }
  else
    printf("%-8.16s  No scan results\n", ifname);

  free(buffer);
  return(0);
}

/******************** WIRELESS EVENT CAPABILITY ********************/

static const char *	event_capa_req[] =
{
  [SIOCSIWNWID	- SIOCIWFIRST] = "Set NWID (kernel generated)",
  [SIOCSIWFREQ	- SIOCIWFIRST] = "Set Frequency/Channel (kernel generated)",
  [SIOCGIWFREQ	- SIOCIWFIRST] = "New Frequency/Channel",
  [SIOCSIWMODE	- SIOCIWFIRST] = "Set Mode (kernel generated)",
  [SIOCGIWTHRSPY - SIOCIWFIRST] = "Spy threshold crossed",
  [SIOCGIWAP	- SIOCIWFIRST] = "New Access Point/Cell address - roaming",
  [SIOCGIWSCAN	- SIOCIWFIRST] = "Scan request completed",
  [SIOCSIWESSID	- SIOCIWFIRST] = "Set ESSID (kernel generated)",
  [SIOCGIWESSID	- SIOCIWFIRST] = "New ESSID",
  [SIOCGIWRATE	- SIOCIWFIRST] = "New bit-rate",
  [SIOCSIWENCODE - SIOCIWFIRST] = "Set Encoding (kernel generated)",
  [SIOCGIWPOWER	- SIOCIWFIRST] = NULL,
};

static const char *	event_capa_evt[] =
{
  [IWEVTXDROP	- IWEVFIRST] = "Tx packet dropped - retry exceeded",
  [IWEVCUSTOM	- IWEVFIRST] = "Custom driver event",
  [IWEVREGISTERED - IWEVFIRST] = "Registered node",
  [IWEVEXPIRED	- IWEVFIRST] = "Expired node",
};

/*------------------------------------------------------------------*/
/*
 * Print the number of available transmit powers for the device
 */
static int
print_event_capa_info(int		skfd,
                      char *		ifname,
                      char *		args[],		/* Command line args */
                      int		count)		/* Args count */
{
  struct iw_range	range;
  int			cmd;

  /* Avoid "Unused parameter" warning */
  args = args; count = count;

  /* Extract range info */
  if((iw_get_range_info(skfd, ifname, &range) < 0) ||
     (range.we_version_compiled < 10))
      fprintf(stderr, "%-8.16s  no wireless event capability information.\n\n",
                      ifname);
  else
    {
#if 0
      /* Debugging ;-) */
      for(cmd = 0x8B00; cmd < 0x8C0F; cmd++)
        {
          int idx = IW_EVENT_CAPA_INDEX(cmd);
          int mask = IW_EVENT_CAPA_MASK(cmd);
          printf("0x%X - %d - %X\n", cmd, idx, mask);
        }
#endif

      printf("%-8.16s  Wireless Events supported :\n", ifname);

      for(cmd = SIOCIWFIRST; cmd <= SIOCGIWPOWER; cmd++)
        {
          int idx = IW_EVENT_CAPA_INDEX(cmd);
          int mask = IW_EVENT_CAPA_MASK(cmd);
          if(range.event_capa[idx] & mask)
            printf("          0x%04X : %s\n",
                   cmd, event_capa_req[cmd - SIOCIWFIRST]);
        }
      for(cmd = IWEVFIRST; cmd <= IWEVEXPIRED; cmd++)
        {
          int idx = IW_EVENT_CAPA_INDEX(cmd);
          int mask = IW_EVENT_CAPA_MASK(cmd);
          if(range.event_capa[idx] & mask)
            printf("          0x%04X : %s\n",
                   cmd, event_capa_evt[cmd - IWEVFIRST]);
        }
      printf("\n");
    }
  return(0);
}

/************************* COMMON UTILITIES *************************/
/*
 * This section was initially written by Michael Tokarev <mjt@tls.msk.ru>
 * but heavily modified by me ;-)
 */

/*------------------------------------------------------------------*/
/*
 * Map command line arguments to the proper procedure...
 */
typedef struct iwlist_entry {
  const char *cmd;
  iw_enum_handler fn;
  int min_count;
  int max_count;
} iwlist_cmd;

static const struct iwlist_entry iwlist_cmds[] = {
  { "scanning",		print_scanning_info,	0, 5 },
  { "frequency",	print_freq_info,	0, 0 },
  { "channel",		print_freq_info,	0, 0 },
  { "bitrate",		print_bitrate_info,	0, 0 },
  { "rate",		print_bitrate_info,	0, 0 },
  { "encryption",	print_keys_info,	0, 0 },
  { "key",		print_keys_info,	0, 0 },
  { "power",		print_pm_info,		0, 0 },
  { "txpower",		print_txpower_info,	0, 0 },
  { "retry",		print_retry_info,	0, 0 },
  { "ap",		print_ap_info,		0, 0 },
  { "accesspoints",	print_ap_info,		0, 0 },
  { "peers",		print_ap_info,		0, 0 },
  { "event",		print_event_capa_info,	0, 0 },
  { NULL, NULL, 0, 0 },
};

/*------------------------------------------------------------------*/
/*
 * Find the most appropriate command matching the command line
 */
static inline const iwlist_cmd *
find_command(const char *	cmd)
{
  const iwlist_cmd *	found = NULL;
  int			ambig = 0;
  unsigned int		len = strlen(cmd);
  int			i;

  /* Go through all commands */
  for(i = 0; iwlist_cmds[i].cmd != NULL; ++i)
    {
      /* No match -> next one */
      if(strncasecmp(iwlist_cmds[i].cmd, cmd, len) != 0)
        continue;

      /* Exact match -> perfect */
      if(len == strlen(iwlist_cmds[i].cmd))
        return &iwlist_cmds[i];

      /* Partial match */
      if(found == NULL)
        /* First time */
        found = &iwlist_cmds[i];
      else
        /* Another time */
        if (iwlist_cmds[i].fn != found->fn)
          ambig = 1;
    }

  if(found == NULL)
    {
      fprintf(stderr, "iwlist: unknown command `%s'\n", cmd);
      return NULL;
    }

  if(ambig)
    {
      fprintf(stderr, "iwlist: command `%s' is ambiguous\n", cmd);
      return NULL;
    }

  return found;
}

/*------------------------------------------------------------------*/
/*
 * Display help
 */
static void iw_usage(int status)
{
  FILE* f = status ? stderr : stdout;
  int i;

  fprintf(f,   "Usage: iwlist [interface] %s\n", iwlist_cmds[0].cmd);
  for(i = 1; iwlist_cmds[i].cmd != NULL; ++i)
    fprintf(f, "              [interface] %s\n", iwlist_cmds[i].cmd);
  exit(status);
}

/******************************* MAIN ********************************/

/*------------------------------------------------------------------*/
/*
 * The main !
 */
int
main(int	argc,
     char **	argv)
{
  int skfd;			/* generic raw socket desc.	*/
  char *dev;			/* device name			*/
  char *cmd;			/* command			*/
  char **args;			/* Command arguments */
  int count;			/* Number of arguments */
  const iwlist_cmd *iwcmd;

  if(argc == 1 || argc > 3)
    iw_usage(1);

  /* Those don't apply to all interfaces */
  if((argc == 2) && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))
    iw_usage(0);
  if((argc == 2) && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")))
    return(iw_print_version_info("iwlist"));

  if(argc == 2)
    {
      cmd = argv[1];
      dev = NULL;
      args = NULL;
      count = 0;
    }
  else
    {
      cmd = argv[2];
      dev = argv[1];
      args = argv + 3;
      count = argc - 3;
    }

  /* find a command */
  iwcmd = find_command(cmd);
  if(iwcmd == NULL)
    return 1;

  /* Check arg numbers */
  if(count < iwcmd->min_count)
    {
      fprintf(stderr, "iwlist: command `%s' needs more arguments\n", cmd);
      return 1;
    }
  if(count > iwcmd->max_count)
    {
      fprintf(stderr, "iwlist: command `%s' needs fewer arguments\n", cmd);
      return 1;
    }

  /* Create a channel to the NET kernel. */
  if((skfd = iw_sockets_open()) < 0)
    {
      perror("socket");
      return -1;
    }

  /* do the actual work */
  if (dev)
    (*iwcmd->fn)(skfd, dev, args, count);
  else
    iw_enum_devices(skfd, iwcmd->fn, args, count);

  /* Close the socket. */
  iw_sockets_close(skfd);

  return 0;
}

⌨️ 快捷键说明

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