예제 #1
0
static inline int llf_print_event(struct iw_event *event,
				  struct iw_range *iwrange, int has_iwrange)
{
    char buffer[128];
    struct in_addr ip;
    rt_table_t *rt;

    /* Now, let's decode the event */
    switch (event->cmd) {

    case IWEVTXDROP:
	DEBUG(LOG_DEBUG, 0, "Tx packet dropped:%s",
	      iw_pr_ether(buffer, event->u.addr.sa_data));


	if (mac_to_ip(&event->u.addr, &ip, this_host.devs[0].ifname) != 0) {
	    DEBUG(LOG_DEBUG, 0, "failed mac_to_ip");
	    return 0;
	}
	//printf("IP=%s\n", ip_to_str(ip));

	rt = rt_table_find(ip);

	if (rt)
	    neighbor_link_break(rt);
	else
	    DEBUG(LOG_DEBUG, 0, "no route for ip=%s", ip_to_str(ip));
	break;

    default:
	DEBUG(LOG_DEBUG, 0, "(Unknown Wireless event 0x%04X)", event->cmd);
    }

    return 0;
}
예제 #2
0
/*
 * Execute a private command on the interface
 */
static int
set_private_cmd(int		skfd,		/* Socket */
		char *		args[],		/* Command line args */
		int		count,		/* Args count */
		char *		ifname,		/* Dev name */
		char *		cmdname,	/* Command name */
		iwprivargs *	priv,		/* Private ioctl description */
		int		priv_num)	/* Number of descriptions */
{
  struct iwreq	wrq;
  u_char	buffer[4096];	/* Only that big in v25 and later */
  int		i = 0;		/* Start with first command arg */
  int		k;		/* Index in private description table */
  int		temp;
  int		subcmd = 0;	/* sub-ioctl index */
  int		offset = 0;	/* Space for sub-ioctl index */

  /* Check if we have a token index.
   * Do it know so that sub-ioctl takes precendence, and so that we
   * don't have to bother with it later on... */
  if((count > 1) && (sscanf(args[0], "[%i]", &temp) == 1))
    {
      subcmd = temp;
      args++;
      count--;
    }

  /* Search the correct ioctl */
  k = -1;
  while((++k < priv_num) && strcmp(priv[k].name, cmdname));

  /* If not found... */
  if(k == priv_num)
    {
      fprintf(stderr, "Invalid command : %s\n", cmdname);
      return(-1);
    }

  /* Watch out for sub-ioctls ! */
  if(priv[k].cmd < SIOCDEVPRIVATE)
    {
      int	j = -1;

      /* Find the matching *real* ioctl */
      while((++j < priv_num) && ((priv[j].name[0] != '\0') ||
				 (priv[j].set_args != priv[k].set_args) ||
				 (priv[j].get_args != priv[k].get_args)));

      /* If not found... */
      if(j == priv_num)
	{
	  fprintf(stderr, "Invalid private ioctl definition for : %s\n",
		  cmdname);
	  return(-1);
	}

      /* Save sub-ioctl number */
      subcmd = priv[k].cmd;
      /* Reserve one int (simplify alignement issues) */
      offset = sizeof(__u32);
      /* Use real ioctl definition from now on */
      k = j;

      printf("<mapping sub-ioctl %s to cmd 0x%X-%d>\n", cmdname,
	     priv[k].cmd, subcmd);
    }

  /* If we have to set some data */
  if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
     (priv[k].set_args & IW_PRIV_SIZE_MASK))
    {
      switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
	{
	case IW_PRIV_TYPE_BYTE:
	  /* Number of args to fetch */
	  wrq.u.data.length = count;
	  if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
	    wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;

	  /* Fetch args */
	  for(; i < wrq.u.data.length; i++) {
	    sscanf(args[i], "%i", &temp);
	    buffer[i] = (char) temp;
	  }
	  break;

	case IW_PRIV_TYPE_INT:
	  /* Number of args to fetch */
	  wrq.u.data.length = count;
	  if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
	    wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;

	  /* Fetch args */
	  for(; i < wrq.u.data.length; i++) {
	    sscanf(args[i], "%i", &temp);
	    ((__s32 *) buffer)[i] = (__s32) temp;
	  }
	  break;

	case IW_PRIV_TYPE_CHAR:
	  if(i < count)
	    {
	      /* Size of the string to fetch */
	      wrq.u.data.length = strlen(args[i]) + 1;
	      if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
		wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;

	      /* Fetch string */
	      memcpy(buffer, args[i], wrq.u.data.length);
	      buffer[sizeof(buffer) - 1] = '\0';
	      i++;
	    }
	  else
	    {
	      wrq.u.data.length = 1;
	      buffer[0] = '\0';
	    }
	  break;

	case IW_PRIV_TYPE_FLOAT:
	  /* Number of args to fetch */
	  wrq.u.data.length = count;
	  if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
	    wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;

	  /* Fetch args */
	  for(; i < wrq.u.data.length; i++) {
	    double		freq;
	    if(sscanf(args[i], "%lg", &(freq)) != 1)
	      {
		printf("Invalid float [%s]...\n", args[i]);
		return(-1);
	      }
	    if(index(args[i], 'G')) freq *= GIGA;
	    if(index(args[i], 'M')) freq *= MEGA;
	    if(index(args[i], 'k')) freq *= KILO;
	    sscanf(args[i], "%i", &temp);
	    iw_float2freq(freq, ((struct iw_freq *) buffer) + i);
	  }
	  break;

	case IW_PRIV_TYPE_ADDR:
	  /* Number of args to fetch */
	  wrq.u.data.length = count;
	  if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
	    wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;

	  /* Fetch args */
	  for(; i < wrq.u.data.length; i++) {
	    if(iw_in_addr(skfd, ifname, args[i],
			  ((struct sockaddr *) buffer) + i) < 0)
	      {
		printf("Invalid address [%s]...\n", args[i]);
		return(-1);
	      }
	  }
	  break;

	default:
	  fprintf(stderr, "Not yet implemented...\n");
	  return(-1);
	}

      if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
	 (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
	{
	  printf("The command %s need exactly %d argument...\n",
		 cmdname, priv[k].set_args & IW_PRIV_SIZE_MASK);
	  return(-1);
	}
    }	/* if args to set */
  else
    {
      wrq.u.data.length = 0L;
    }

  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);

  /* Those two tests are important. They define how the driver
   * will have to handle the data */
  if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
      ((iw_get_priv_size(priv[k].set_args) + offset) <= IFNAMSIZ))
    {
      /* First case : all SET args fit within wrq */
      if(offset)
	wrq.u.mode = subcmd;
      memcpy(wrq.u.name + offset, buffer, IFNAMSIZ - offset);
    }
  else
    {
      if((priv[k].set_args == 0) &&
	 (priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
	 (iw_get_priv_size(priv[k].get_args) <= IFNAMSIZ))
	{
	  /* Second case : no SET args, GET args fit within wrq */
	  if(offset)
	    wrq.u.mode = subcmd;
	}
      else
	{
	  /* Thirst case : args won't fit in wrq, or variable number of args */
	  wrq.u.data.pointer = (caddr_t) buffer;
	  wrq.u.data.flags = subcmd;
	}
    }

  /* Perform the private ioctl */
  if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
    {
      fprintf(stderr, "Interface doesn't accept private ioctl...\n");
      fprintf(stderr, "%s (%X): %s\n", cmdname, priv[k].cmd, strerror(errno));
      return(-1);
    }

  /* If we have to get some data */
  if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
     (priv[k].get_args & IW_PRIV_SIZE_MASK))
    {
      int	j;
      int	n = 0;		/* number of args */

      printf("%-8.8s  %s:", ifname, cmdname);

      /* Check where is the returned data */
      if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
	 (iw_get_priv_size(priv[k].get_args) <= IFNAMSIZ))
	{
	  memcpy(buffer, wrq.u.name, IFNAMSIZ);
	  n = priv[k].get_args & IW_PRIV_SIZE_MASK;
	}
      else
	n = wrq.u.data.length;

      switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
	{
	case IW_PRIV_TYPE_BYTE:
	  /* Display args */
	  for(j = 0; j < n; j++)
	    printf("%d  ", buffer[j]);
	  printf("\n");
	  break;

	case IW_PRIV_TYPE_INT:
	  /* Display args */
	  for(j = 0; j < n; j++)
	    printf("%d  ", ((__s32 *) buffer)[j]);
	  printf("\n");
	  break;

	case IW_PRIV_TYPE_CHAR:
	  /* Display args */
	  buffer[wrq.u.data.length - 1] = '\0';
	  printf("%s\n", buffer);
	  break;

	case IW_PRIV_TYPE_FLOAT:
	  {
	    double		freq;
	    /* Display args */
	    for(j = 0; j < n; j++)
	      {
		freq = iw_freq2float(((struct iw_freq *) buffer) + j);
		if(freq >= GIGA)
		  printf("%gG  ", freq / GIGA);
		else
		  if(freq >= MEGA)
		  printf("%gM  ", freq / MEGA);
		else
		  printf("%gk  ", freq / KILO);
	      }
	    printf("\n");
	  }
	  break;

	case IW_PRIV_TYPE_ADDR:
	  {
	    char		scratch[128];
	    struct sockaddr *	hwa;
	    /* Display args */
	    for(j = 0; j < n; j++)
	      {
		hwa = ((struct sockaddr *) buffer) + j;
		if(j)
		  printf("           %.*s",
			 (int) strlen(cmdname), "                ");
		printf("%s\n", iw_pr_ether(scratch, hwa->sa_data));
	      }
	  }
	  break;

	default:
	  fprintf(stderr, "Not yet implemented...\n");
	  return(-1);
	}
    }	/* if args to set */

  return(0);
}
예제 #3
0
/*
 * Print on the screen in a neat fashion all the info we have collected
 * on a device.
 */
static void
display_info(struct wireless_info *	info,
	     char *			ifname)
{
  char		buffer[128];	/* Temporary buffer */

  /* One token is more of less 5 characters, 14 tokens per line */
  int	tokens = 3;	/* For name */

  /* Display device name and wireless name (name of the protocol used) */
  printf("%-8.8s  %s  ", ifname, info->name);

  /* Display ESSID (extended network), if any */
  if(info->has_essid)
    {
      if(info->essid_on)
	{
	  /* Does it have an ESSID index ? */
	  if((info->essid_on & IW_ENCODE_INDEX) > 1)
	    printf("ESSID:\"%s\" [%d]  ", info->essid,
		   (info->essid_on & IW_ENCODE_INDEX));
	  else
	    printf("ESSID:\"%s\"  ", info->essid);
	}
      else
	printf("ESSID:off/any  ");
    }

  /* Display NickName (station name), if any */
  if(info->has_nickname)
    printf("Nickname:\"%s\"", info->nickname);

  /* Formatting */
  if(info->has_essid || info->has_nickname)
    {
      printf("\n          ");
      tokens = 0;
    }

  /* Display Network ID */
  if(info->has_nwid)
    {
      /* Note : should display proper number of digit according to info
       * in range structure */
      if(info->nwid.disabled)
	printf("NWID:off/any  ");
      else
	printf("NWID:%X  ", info->nwid.value);
      tokens +=2;
    }

  /* Display the current mode of operation */
  if(info->has_mode)
    {
      printf("Mode:%s  ", iw_operation_mode[info->mode]);
      tokens +=3;
    }

  /* Display frequency / channel */
  if(info->has_freq)
    {
      iw_print_freq(buffer, info->freq);
      printf("%s  ", buffer);
      tokens +=4;
    }

  /* Display the address of the current Access Point */
  if(info->has_ap_addr)
    {
      /* A bit of clever formatting */
      if(tokens > 8)
	{
	  printf("\n          ");
	  tokens = 0;
	}
      tokens +=6;

      /* Oups ! No Access Point in Ad-Hoc mode */
      if((info->has_mode) && (info->mode == IW_MODE_ADHOC))
	printf("Cell:");
      else
	printf("Access Point:");
      printf(" %s  ", iw_pr_ether(buffer, info->ap_addr.sa_data));
    }

  /* Display the currently used/set bit-rate */
  if(info->has_bitrate)
    {
      /* A bit of clever formatting */
      if(tokens > 11)
	{
	  printf("\n          ");
	  tokens = 0;
	}
      tokens +=3;

      /* Display it */
      iw_print_bitrate(buffer, info->bitrate.value);
      printf("Bit Rate%c%s   ", (info->bitrate.fixed ? '=' : ':'), buffer);
    }

#if WIRELESS_EXT > 9
  /* Display the Transmit Power */
  if(info->has_txpower)
    {
      /* A bit of clever formatting */
      if(tokens > 11)
	{
	  printf("\n          ");
	  tokens = 0;
	}
      tokens +=3;

      /* Disabled ? */
      if(info->txpower.disabled)
	printf("Tx-Power:off   ");
      else
	{
	  int		dbm;

	  /* Fixed ? */
	  if(info->txpower.fixed)
	    printf("Tx-Power=");
	  else
	    printf("Tx-Power:");

	  /* Convert everything to dBm */
	  if(info->txpower.flags & IW_TXPOW_MWATT)
	    dbm = iw_mwatt2dbm(info->txpower.value);
	  else
	    dbm = info->txpower.value;

	  /* Display */
	  printf("%d dBm   ", dbm);
	}
    }
#endif

  /* Display sensitivity */
  if(info->has_sens)
    {
      /* A bit of clever formatting */
      if(tokens > 10)
	{
	  printf("\n          ");
	  tokens = 0;
	}
      tokens +=4;

      /* Fixed ? */
      if(info->sens.fixed)
	printf("Sensitivity=");
      else
	printf("Sensitivity:");

      if(info->has_range)
	/* Display in dBm ? */
	if(info->sens.value < 0)
	  printf("%d dBm  ", info->sens.value);
	else
	  printf("%d/%d  ", info->sens.value, info->range.sensitivity);
      else
	printf("%d  ", info->sens.value);
    }

  printf("\n          ");
  tokens = 0;

#if WIRELESS_EXT > 10
  /* Display retry limit/lifetime information */
  if(info->has_retry)
    {
      printf("Retry");
      /* Disabled ? */
      if(info->retry.disabled)
	printf(":off");
      else
	{
	  /* Let's check the value and its type */
	  if(info->retry.flags & IW_RETRY_TYPE)
	    {
	      iw_print_retry_value(buffer,
				   info->retry.value, info->retry.flags);
	      printf("%s", buffer);
	    }

	  /* Let's check if nothing (simply on) */
	  if(info->retry.flags == IW_RETRY_ON)
	    printf(":on");
 	}
      printf("   ");
      tokens += 5;	/* Between 3 and 5, depend on flags */
    }
#endif	/* WIRELESS_EXT > 10 */

  /* Display the RTS threshold */
  if(info->has_rts)
    {
      /* Disabled ? */
      if(info->rts.disabled)
	printf("RTS thr:off   ");
      else
	{
	  /* Fixed ? */
	  if(info->rts.fixed)
	    printf("RTS thr=");
	  else
	    printf("RTS thr:");

	  printf("%d B   ", info->rts.value);
	}
      tokens += 3;
    }

  /* Display the fragmentation threshold */
  if(info->has_frag)
    {
      /* A bit of clever formatting */
      if(tokens > 10)
	{
	  printf("\n          ");
	  tokens = 0;
	}
      tokens +=4;

      /* Disabled ? */
      if(info->frag.disabled)
	printf("Fragment thr:off");
      else
	{
	  /* Fixed ? */
	  if(info->frag.fixed)
	    printf("Fragment thr=");
	  else
	    printf("Fragment thr:");

	  printf("%d B   ", info->frag.value);
	}
    }

  /* Formating */
  if(tokens > 0)
    printf("\n          ");

  /* Display encryption information */
  /* Note : we display only the "current" key, use iwlist to list all keys */
  if(info->has_key)
    {
      printf("Encryption key:");
      if((info->key_flags & IW_ENCODE_DISABLED) || (info->key_size == 0))
	printf("off\n          ");
      else
	{
	  /* Display the key */
	  iw_print_key(buffer, info->key, info->key_size, info->key_flags);
	  printf("%s", buffer);

	  /* Other info... */
	  if((info->key_flags & IW_ENCODE_INDEX) > 1)
	    printf(" [%d]", info->key_flags & IW_ENCODE_INDEX);
	  if(info->key_flags & IW_ENCODE_RESTRICTED)
	    printf("   Security mode:restricted");
	  if(info->key_flags & IW_ENCODE_OPEN)
	    printf("   Security mode:open");
	  printf("\n          ");
 	}
    }

  /* Display Power Management information */
  /* Note : we display only one parameter, period or timeout. If a device
   * (such as HiperLan) has both, the user need to use iwlist... */
  if(info->has_power)	/* I hope the device has power ;-) */
    {
      printf("Power Management");
      /* Disabled ? */
      if(info->power.disabled)
	printf(":off\n          ");
      else
	{
	  /* Let's check the value and its type */
	  if(info->power.flags & IW_POWER_TYPE)
	    {
	      iw_print_pm_value(buffer, info->power.value, info->power.flags);
	      printf("%s  ", buffer);
	    }

	  /* Let's check the mode */
	  iw_print_pm_mode(buffer, info->power.flags);
	  printf("%s", buffer);

	  /* Let's check if nothing (simply on) */
	  if(info->power.flags == IW_POWER_ON)
	    printf(":on");
	  printf("\n          ");
 	}
    }

  /* Display statistics */
  if(info->has_stats)
    {
      info->stats.qual.updated = 0x0;	/* Not that reliable, disable */
      iw_print_stats(buffer, &info->stats.qual, &info->range, info->has_range);
      printf("Link %s\n", buffer);

#if WIRELESS_EXT > 11
      printf("          Rx invalid nwid:%d  Rx invalid crypt:%d  Rx invalid frag:%d\n          Tx excessive retries:%d  Invalid misc:%d   Missed beacon:%d\n",
	     info->stats.discard.nwid,
	     info->stats.discard.code,
	     info->stats.discard.fragment,
	     info->stats.discard.retries,
	     info->stats.discard.misc,
	     info->stats.miss.beacon);
#else /* WIRELESS_EXT > 11 */
      printf("          Rx invalid nwid:%d  invalid crypt:%d  invalid misc:%d\n",
	     info->stats.discard.nwid,
	     info->stats.discard.code,
	     info->stats.discard.misc);
#endif /* WIRELESS_EXT > 11 */
    }

  printf("\n");
}
예제 #4
0
/*
 * Print one element from the scanning results
 */
static inline int
print_event_token(struct iw_event *	event,	/* Extracted token */
		  struct iw_range *	iwrange,	/* Range info */
		  int			has_range)
{
  char		buffer[128];	/* Temporary buffer */

  /* Now, let's decode the event */
  switch(event->cmd)
    {
      /* ----- set events ----- */
      /* Events that result from a "SET XXX" operation by the user */
    case SIOCSIWNWID:
      if(event->u.nwid.disabled)
	printf("NWID:off/any\n");
      else
	printf("NWID:%X\n", event->u.nwid.value);
      break;
    case SIOCSIWFREQ:
      {
	float		freq;			/* Frequency/channel */
	freq = iw_freq2float(&(event->u.freq));
	iw_print_freq(buffer, freq);
	printf("%s\n", buffer);
      }
      break;
    case SIOCSIWMODE:
      printf("Mode:%s\n",
	     iw_operation_mode[event->u.mode]);
      break;
    case SIOCSIWESSID:
      {
	char essid[IW_ESSID_MAX_SIZE+1];
	if((event->u.essid.pointer) && (event->u.essid.length))
	  memcpy(essid, event->u.essid.pointer, event->u.essid.length);
	essid[event->u.essid.length] = '\0';
	if(event->u.essid.flags)
	  {
	    /* Does it have an ESSID index ? */
	    if((event->u.essid.flags & IW_ENCODE_INDEX) > 1)
	      printf("ESSID:\"%s\" [%d]\n", essid,
		     (event->u.essid.flags & IW_ENCODE_INDEX));
	    else
	      printf("ESSID:\"%s\"\n", essid);
	  }
	else
	  printf("ESSID:off/any\n");
      }
      break;
    case SIOCSIWENCODE:
      {
	unsigned char	key[IW_ENCODING_TOKEN_MAX];
	if(event->u.data.pointer)
	  memcpy(key, event->u.essid.pointer, event->u.data.length);
	else
	  event->u.data.flags |= IW_ENCODE_NOKEY;
	printf("Encryption key:");
	if(event->u.data.flags & IW_ENCODE_DISABLED)
	  printf("off\n");
	else
	  {
	    /* Display the key */
	    iw_print_key(buffer, key, event->u.data.length,
			 event->u.data.flags);
	    printf("%s", buffer);

	    /* Other info... */
	    if((event->u.data.flags & IW_ENCODE_INDEX) > 1)
	      printf(" [%d]", event->u.data.flags & IW_ENCODE_INDEX);
	    if(event->u.data.flags & IW_ENCODE_RESTRICTED)
	      printf("   Encryption mode:restricted");
	    if(event->u.data.flags & IW_ENCODE_OPEN)
	      printf("   Encryption mode:open");
	    printf("\n");
	  }
      }
      break;
      /* ----- driver events ----- */
      /* Events generated by the driver when something important happens */
    case SIOCGIWAP:
      printf("New Access Point/Cell address:%s\n",
	     iw_pr_ether(buffer, event->u.ap_addr.sa_data));
      break;
    case SIOCGIWSCAN:
      printf("Scan request completed\n");
      break;
    case IWEVTXDROP:
      printf("Tx packet dropped:%s\n",
	     iw_pr_ether(buffer, event->u.addr.sa_data));
      break;
#if WIRELESS_EXT > 14
    case IWEVCUSTOM:
      {
	char custom[IW_CUSTOM_MAX+1];
	if((event->u.data.pointer) && (event->u.data.length))
	  memcpy(custom, event->u.data.pointer, event->u.data.length);
	custom[event->u.data.length] = '\0';
	printf("Custom driver event:%s\n", custom);
      }
      break;
    case IWEVREGISTERED:
      printf("Registered node:%s\n",
	     iw_pr_ether(buffer, event->u.addr.sa_data));
      break;
    case IWEVEXPIRED:
      printf("Expired node:%s\n",
	     iw_pr_ether(buffer, event->u.addr.sa_data));
      break;
#endif /* WIRELESS_EXT > 14 */
      /* ----- junk ----- */
      /* other junk not currently in use */
    case SIOCGIWRATE:
      iw_print_bitrate(buffer, event->u.bitrate.value);
      printf("Bit Rate:%s\n", buffer);
      break;
    case IWEVQUAL:
      {
	event->u.qual.updated = 0x0;	/* Not that reliable, disable */
	iw_print_stats(buffer, &event->u.qual, iwrange, has_range);
	printf("Link %s\n", buffer);
	break;
      }
    default:
      printf("(Unknown Wireless event 0x%04X)\n", event->cmd);
    }	/* switch(event->cmd) */

  return(0);
}