Ejemplo n.º 1
0
/*
 * Set AP Address
 */
static int
set_apaddr_info(int		skfd,
		char *		ifname,
		char *		args[],		/* Command line args */
		int		count)		/* Args count */
{
  struct iwreq		wrq;

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

  if((!strcasecmp(args[0], "auto")) ||
     (!strcasecmp(args[0], "any")))
    {
      /* Send a broadcast address */
      iw_broad_ether(&(wrq.u.ap_addr));
    }
  else
    {
      if(!strcasecmp(args[0], "off"))
	{
	  /* Send a NULL address */
	  iw_null_ether(&(wrq.u.ap_addr));
	}
      else
	{
	  /* Get the address and check if the interface supports it */
	  if(iw_in_addr(skfd, ifname, args[0], &(wrq.u.ap_addr)) < 0)
	    {
	      errarg = 0;
	      return(IWERR_ARG_TYPE);
	    }
	}
    }

  if(iw_set_ext(skfd, ifname, SIOCSIWAP, &wrq) < 0)
    return(IWERR_SET_EXT);

  /* 1 args */
  return(1);
}
Ejemplo n.º 2
0
/*
 * Set the wireless options requested on command line
 * This function is too long and probably should be split,
 * because it look like the perfect definition of spaghetti code,
 * but I'm way to lazy
 */
static int
set_info(int		skfd,		/* The socket */
	 char *		args[],		/* Command line args */
	 int		count,		/* Args count */
	 char *		ifname)		/* Dev name */
{
  struct iwreq		wrq;
  int			i;

  /* if nothing after the device name - will never happen */
  if(count < 1)
    {
      fprintf(stderr, "Error : too few arguments.\n");
      return(-1);
    }

  /* The other args on the line specify options to be set... */
  for(i = 0; i < count; i++)
    {
      /* ---------- Commit changes to driver ---------- */
      if(!strncmp(args[i], "commit", 6))
	{
	  /* No args */
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWCOMMIT, &wrq,
			 "Commit changes");
	  continue;
	}

      /* ---------- Set network ID ---------- */
      if((!strcasecmp(args[i], "nwid")) ||
	 (!strcasecmp(args[i], "domain")))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set NWID", SIOCSIWNWID);
	  if((!strcasecmp(args[i], "off")) ||
	     (!strcasecmp(args[i], "any")))
	    wrq.u.nwid.disabled = 1;
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old nwid */
		IW_GET_EXT_ERR(skfd, ifname, SIOCGIWNWID, &wrq,
			       "Set NWID");
		wrq.u.nwid.disabled = 0;
	      }
	    else
	      if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
		 != 1)
		ABORT_ARG_TYPE("Set NWID", SIOCSIWNWID, args[i]);
	      else
		wrq.u.nwid.disabled = 0;
	  wrq.u.nwid.fixed = 1;

	  /* Set new nwid */
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNWID, &wrq,
			 "Set NWID");
	  continue;
	}

      /* ---------- Set frequency / channel ---------- */
      if((!strncmp(args[i], "freq", 4)) ||
	 (!strcmp(args[i], "channel")))
	{
	  double		freq;

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Frequency", SIOCSIWFREQ);
	  if(sscanf(args[i], "%lg", &(freq)) != 1)
	    ABORT_ARG_TYPE("Set Frequency", SIOCSIWFREQ, args[i]);
	  if(index(args[i], 'G')) freq *= GIGA;
	  if(index(args[i], 'M')) freq *= MEGA;
	  if(index(args[i], 'k')) freq *= KILO;

	  iw_float2freq(freq, &(wrq.u.freq));

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq,
			 "Set Frequency");
	  continue;
	}

      /* ---------- Set sensitivity ---------- */
      if(!strncmp(args[i], "sens", 4))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set Sensitivity", SIOCSIWSENS);
	  if(sscanf(args[i], "%i", &(wrq.u.sens.value)) != 1)
	    ABORT_ARG_TYPE("Set Sensitivity", SIOCSIWSENS, args[i]);

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWSENS, &wrq,
			 "Set Sensitivity");
	  continue;
	}

      /* ---------- Set encryption stuff ---------- */
      if((!strncmp(args[i], "enc", 3)) ||
	 (!strcmp(args[i], "key")))
	{
	  unsigned char	key[IW_ENCODING_TOKEN_MAX];

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Encode", SIOCSIWENCODE);

	  if(!strcasecmp(args[i], "on"))
	    {
	      /* Get old encryption information */
	      wrq.u.data.pointer = (caddr_t) key;
	      wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
	      wrq.u.data.flags = 0;
	      IW_GET_EXT_ERR(skfd, ifname, SIOCGIWENCODE, &wrq,
			     "Set Encode");
	      wrq.u.data.flags &= ~IW_ENCODE_DISABLED;	/* Enable */
	    }
	  else
	    {
	      int	gotone = 0;
	      int	oldone;
	      int	keylen;
	      int	temp;

	      wrq.u.data.pointer = (caddr_t) NULL;
	      wrq.u.data.flags = 0;
	      wrq.u.data.length = 0;

	      /* Allow arguments in any order (it's safe) */
	      do
		{
		  oldone = gotone;

		  /* -- Check for the key -- */
		  if(i < count)
		    {
		      keylen = iw_in_key_full(skfd, ifname,
					      args[i], key, &wrq.u.data.flags);
		      if(keylen > 0)
			{
			  wrq.u.data.length = keylen;
			  wrq.u.data.pointer = (caddr_t) key;
			  ++i;
			  gotone++;
			}
		    }

		  /* -- Check for token index -- */
		  if((i < count) &&
		     (sscanf(args[i], "%i", &temp) == 1) &&
		     (temp > 0) && (temp < IW_ENCODE_INDEX))
		    {
		      wrq.u.encoding.flags |= temp;
		      ++i;
		      gotone++;
		    }

		  /* -- Check the various flags -- */
		  if((i < count) && (!strcasecmp(args[i], "off")))
		    {
		      wrq.u.data.flags |= IW_ENCODE_DISABLED;
		      ++i;
		      gotone++;
		    }
		  if((i < count) && (!strcasecmp(args[i], "open")))
		    {
		      wrq.u.data.flags |= IW_ENCODE_OPEN;
		      ++i;
		      gotone++;
		    }
		  if((i < count) && (!strncasecmp(args[i], "restricted", 5)))
		    {
		      wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
		      ++i;
		      gotone++;
		    }
#if WIRELESS_EXT > 15
		  if((i < count) && (!strncasecmp(args[i], "temporary", 4)))
		    {
		      wrq.u.data.flags |= IW_ENCODE_TEMP;
		      ++i;
		      gotone++;
		    }
#endif
		}
	      while(gotone != oldone);

	      /* Pointer is absent in new API */
	      if(wrq.u.data.pointer == NULL)
		wrq.u.data.flags |= IW_ENCODE_NOKEY;

	      /* Check if we have any invalid argument */
	      if(!gotone)
		ABORT_ARG_TYPE("Set Encode", SIOCSIWENCODE, args[i]);
	      /* Get back to last processed argument */
	      --i;
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWENCODE, &wrq,
			 "Set Encode");
	  continue;
  	}

      /* ---------- Set ESSID ---------- */
      if(!strcasecmp(args[i], "essid"))
	{
	  char		essid[IW_ESSID_MAX_SIZE + 1];

	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
	  if((!strcasecmp(args[i], "off")) ||
	     (!strcasecmp(args[i], "any")))
	    {
	      wrq.u.essid.flags = 0;
	      essid[0] = '\0';
	    }
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old essid */
		wrq.u.essid.pointer = (caddr_t) essid;
		wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
		wrq.u.essid.flags = 0;
		IW_GET_EXT_ERR(skfd, ifname, SIOCGIWESSID, &wrq,
			       "Set ESSID");
		wrq.u.essid.flags = 1;
	      }
	    else
	      {
		/* '-' allow to escape the ESSID string, allowing
		 * to set it to the string "any" or "off".
		 * This is a big ugly, but it will do for now */
		if(!strcmp(args[i], "-"))
		  {
		    i++;
		    if(i >= count)
		      ABORT_ARG_NUM("Set ESSID", SIOCSIWESSID);
		  }

		/* Check the size of what the user passed us to avoid
		 * buffer overflows */
		if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
		  ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE);
		else
		  {
		    int		temp;

		    wrq.u.essid.flags = 1;
		    strcpy(essid, args[i]);	/* Size checked, all clear */

		    /* Check for ESSID index */
		    if(((i+1) < count) &&
		       (sscanf(args[i+1], "[%i]", &temp) == 1) &&
		       (temp > 0) && (temp < IW_ENCODE_INDEX))
		      {
			wrq.u.essid.flags = temp;
			++i;
		      }
		  }
	      }

	  wrq.u.essid.pointer = (caddr_t) essid;
	  wrq.u.essid.length = strlen(essid) + 1;
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq,
			 "Set ESSID");
	  continue;
	}

      /* ---------- Set AP address ---------- */
      if(!strcasecmp(args[i], "ap"))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set AP Address", SIOCSIWAP);

	  if((!strcasecmp(args[i], "auto")) ||
	     (!strcasecmp(args[i], "any")))
	    {
	      /* Send a broadcast address */
	      iw_broad_ether(&(wrq.u.ap_addr));
	    }
	  else
	    {
	      if(!strcasecmp(args[i], "off"))
		{
		  /* Send a NULL address */
		  iw_null_ether(&(wrq.u.ap_addr));
		}
	      else
		{
		  /* Get the address and check if the interface supports it */
		  if(iw_in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
		    ABORT_ARG_TYPE("Set AP Address", SIOCSIWAP, args[i-1]);
		}
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWAP, &wrq,
			 "Set AP Address");
	  continue;
	}

      /* ---------- Set NickName ---------- */
      if(!strncmp(args[i], "nick", 4))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set Nickname", SIOCSIWNICKN);
	  if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
	    ABORT_ARG_SIZE("Set Nickname", SIOCSIWNICKN, IW_ESSID_MAX_SIZE);

	  wrq.u.essid.pointer = (caddr_t) args[i];
	  wrq.u.essid.length = strlen(args[i]) + 1;
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWNICKN, &wrq,
			 "Set Nickname");
	  continue;
	}

      /* ---------- Set Bit-Rate ---------- */
      if((!strncmp(args[i], "bit", 3)) ||
	 (!strcmp(args[i], "rate")))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set Bit Rate", SIOCSIWRATE);
	  if(!strcasecmp(args[i], "auto"))
	    {
	      wrq.u.bitrate.value = -1;
	      wrq.u.bitrate.fixed = 0;
	    }
	  else
	    {
	      if(!strcasecmp(args[i], "fixed"))
		{
		  /* Get old bitrate */
		  IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRATE, &wrq,
				 "Set Bit Rate");
		  wrq.u.bitrate.fixed = 1;
		}
	      else			/* Should be a numeric value */
		{
		  double		brate;

		  if(sscanf(args[i], "%lg", &(brate)) != 1)
		    ABORT_ARG_TYPE("Set Bit Rate", SIOCSIWRATE, args[i]);
		  if(index(args[i], 'G')) brate *= GIGA;
		  if(index(args[i], 'M')) brate *= MEGA;
		  if(index(args[i], 'k')) brate *= KILO;
		  wrq.u.bitrate.value = (long) brate;
		  wrq.u.bitrate.fixed = 1;

		  /* Check for an additional argument */
		  if(((i+1) < count) &&
		     (!strcasecmp(args[i+1], "auto")))
		    {
		      wrq.u.bitrate.fixed = 0;
		      ++i;
		    }
		  if(((i+1) < count) &&
		     (!strcasecmp(args[i+1], "fixed")))
		    {
		      wrq.u.bitrate.fixed = 1;
		      ++i;
		    }
		}
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRATE, &wrq,
			 "Set Bit Rate");
	  continue;
	}

      /* ---------- Set RTS threshold ---------- */
      if(!strncasecmp(args[i], "rts", 3))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set RTS Threshold", SIOCSIWRTS);
	  wrq.u.rts.value = -1;
	  wrq.u.rts.fixed = 1;
	  wrq.u.rts.disabled = 0;
	  if(!strcasecmp(args[i], "off"))
	    wrq.u.rts.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "auto"))
	      wrq.u.rts.fixed = 0;
	    else
	      {
		if(!strcasecmp(args[i], "fixed"))
		  {
		    /* Get old RTS threshold */
		    IW_GET_EXT_ERR(skfd, ifname, SIOCGIWRTS, &wrq,
				   "Set RTS Threshold");
		    wrq.u.rts.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  if(sscanf(args[i], "%li", (unsigned long *) &(wrq.u.rts.value))
		     != 1)
		    ABORT_ARG_TYPE("Set RTS Threshold", SIOCSIWRTS, args[i]);
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRTS, &wrq,
			 "Set RTS Threshold");
	  continue;
	}

      /* ---------- Set fragmentation threshold ---------- */
      if(!strncmp(args[i], "frag", 4))
	{
	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set Fragmentation Threshold", SIOCSIWFRAG);
	  wrq.u.frag.value = -1;
	  wrq.u.frag.fixed = 1;
	  wrq.u.frag.disabled = 0;
	  if(!strcasecmp(args[i], "off"))
	    wrq.u.frag.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "auto"))
	      wrq.u.frag.fixed = 0;
	    else
	      {
		if(!strcasecmp(args[i], "fixed"))
		  {
		    /* Get old fragmentation threshold */
		    IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFRAG, &wrq,
				   "Set Fragmentation Threshold");
		    wrq.u.frag.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  if(sscanf(args[i], "%li",
			    (unsigned long *) &(wrq.u.frag.value))
		     != 1)
		    ABORT_ARG_TYPE("Set Fragmentation Threshold", SIOCSIWFRAG,
				   args[i]);
	    }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFRAG, &wrq,
			 "Set Fragmentation Threshold");
	  continue;
	}

      /* ---------- Set operation mode ---------- */
      if(!strcmp(args[i], "mode"))
	{
	  int	k;

	  i++;
	  if(i >= count)
	    ABORT_ARG_NUM("Set Mode", SIOCSIWMODE);

	  if(sscanf(args[i], "%i", &k) != 1)
	    {
	      k = 0;
	      while((k < IW_NUM_OPER_MODE) &&
		    strncasecmp(args[i], iw_operation_mode[k], 3))
		k++;
	    }
	  if((k >= IW_NUM_OPER_MODE) || (k < 0))
	    ABORT_ARG_TYPE("Set Mode", SIOCSIWMODE, args[i]);

	  wrq.u.mode = k;
	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq,
			 "Set Mode");
	  continue;
	}

      /* ---------- Set Power Management ---------- */
      if(!strncmp(args[i], "power", 3))
	{
	  if(++i >= count)
	    ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);

	  if(!strcasecmp(args[i], "off"))
	    wrq.u.power.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old Power info */
		IW_GET_EXT_ERR(skfd, ifname, SIOCGIWPOWER, &wrq,
			       "Set Power Management");
		wrq.u.power.disabled = 0;
	      }
	    else
	      {
		double		temp;
		int		gotone = 0;
		/* Default - nope */
		wrq.u.power.flags = IW_POWER_ON;
		wrq.u.power.disabled = 0;

		/* Check value modifier */
		if(!strcasecmp(args[i], "min"))
		  {
		    wrq.u.power.flags |= IW_POWER_MIN;
		    if(++i >= count)
		      ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		  }
		else
		  if(!strcasecmp(args[i], "max"))
		    {
		      wrq.u.power.flags |= IW_POWER_MAX;
		      if(++i >= count)
			ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		    }

		/* Check value type */
		if(!strcasecmp(args[i], "period"))
		  {
		    wrq.u.power.flags |= IW_POWER_PERIOD;
		    if(++i >= count)
		      ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		  }
		else
		  if(!strcasecmp(args[i], "timeout"))
		    {
		      wrq.u.power.flags |= IW_POWER_TIMEOUT;
		      if(++i >= count)
			ABORT_ARG_NUM("Set Power Management", SIOCSIWPOWER);
		    }

		/* Is there any value to grab ? */
		if(sscanf(args[i], "%lg", &(temp)) == 1)
		  {
		    temp *= MEGA;	/* default = s */
		    if(index(args[i], 'u')) temp /= MEGA;
		    if(index(args[i], 'm')) temp /= KILO;
		    wrq.u.power.value = (long) temp;
		    if((wrq.u.power.flags & IW_POWER_TYPE) == 0)
		      wrq.u.power.flags |= IW_POWER_PERIOD;
		    ++i;
		    gotone = 1;
		  }

		/* Now, check the mode */
		if(i < count)
		  {
		    if(!strcasecmp(args[i], "all"))
		      wrq.u.power.flags |= IW_POWER_ALL_R;
		    if(!strncasecmp(args[i], "unicast", 4))
		      wrq.u.power.flags |= IW_POWER_UNICAST_R;
		    if(!strncasecmp(args[i], "multicast", 5))
		      wrq.u.power.flags |= IW_POWER_MULTICAST_R;
		    if(!strncasecmp(args[i], "force", 5))
		      wrq.u.power.flags |= IW_POWER_FORCE_S;
		    if(!strcasecmp(args[i], "repeat"))
		      wrq.u.power.flags |= IW_POWER_REPEATER;
		    if(wrq.u.power.flags & IW_POWER_MODE)
		      {
			++i;
			gotone = 1;
		      }
		  }
		if(!gotone)
		  ABORT_ARG_TYPE("Set Power Management", SIOCSIWPOWER,
				 args[i]);
		--i;
	      }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWPOWER, &wrq,
		       "Set Power Management");
	  continue;
  	}

#if WIRELESS_EXT > 9
      /* ---------- Set Transmit-Power ---------- */
      if(!strncmp(args[i], "txpower", 3))
	{
	  struct iw_range	range;

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Tx Power", SIOCSIWTXPOW);

	  /* Extract range info */
	  if(iw_get_range_info(skfd, ifname, &range) < 0)
	    memset(&range, 0, sizeof(range));

	  /* Prepare the request */
	  wrq.u.txpower.value = -1;
	  wrq.u.txpower.fixed = 1;
	  wrq.u.txpower.disabled = 0;
	  wrq.u.data.flags = IW_TXPOW_DBM;
	  if(!strcasecmp(args[i], "off"))
	    wrq.u.txpower.disabled = 1;	/* i.e. turn radio off */
	  else
	    if(!strcasecmp(args[i], "auto"))
	      wrq.u.txpower.fixed = 0;	/* i.e. use power control */
	    else
	      {
		if(!strcasecmp(args[i], "fixed"))
		  {
		    /* Get old tx-power */
		    IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
				   "Set Tx Power");
		    wrq.u.txpower.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  {
		    int		power;
		    int		ismwatt = 0;

		    /* Get the value */
		    if(sscanf(args[i], "%i", &(power)) != 1)
		      ABORT_ARG_TYPE("Set Tx Power", SIOCSIWTXPOW, args[i]);

		    /* Check if milliwatt */
		    ismwatt = (index(args[i], 'm') != NULL);

		    /* Convert */
		    if(range.txpower_capa & IW_TXPOW_MWATT)
		      {
			if(!ismwatt)
			  power = iw_dbm2mwatt(power);
			wrq.u.data.flags = IW_TXPOW_MWATT;
		      }
		    else
		      {
			if(ismwatt)
			  power = iw_mwatt2dbm(power);
			wrq.u.data.flags = IW_TXPOW_DBM;
		      }
		    wrq.u.txpower.value = power;

		    /* Check for an additional argument */
		    if(((i+1) < count) &&
		       (!strcasecmp(args[i+1], "auto")))
		      {
			wrq.u.txpower.fixed = 0;
			++i;
		      }
		    if(((i+1) < count) &&
		       (!strcasecmp(args[i+1], "fixed")))
		      {
			wrq.u.txpower.fixed = 1;
			++i;
		      }
		  }
	      }

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq,
			 "Set Tx Power");
	  continue;
	}
#endif

#if WIRELESS_EXT > 10
      /* ---------- Set Retry limit ---------- */
      if(!strncmp(args[i], "retry", 3))
	{
	  double		temp;
	  int		gotone = 0;

	  if(++i >= count)
	    ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);

	  /* Default - nope */
	  wrq.u.retry.flags = IW_RETRY_LIMIT;
	  wrq.u.retry.disabled = 0;

	  /* Check value modifier */
	  if(!strcasecmp(args[i], "min"))
	    {
	      wrq.u.retry.flags |= IW_RETRY_MIN;
	      if(++i >= count)
		ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	    }
	  else
	    if(!strcasecmp(args[i], "max"))
	      {
		wrq.u.retry.flags |= IW_RETRY_MAX;
		if(++i >= count)
		  ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	      }

	  /* Check value type */
	  if(!strcasecmp(args[i], "limit"))
	    {
	      wrq.u.retry.flags |= IW_RETRY_LIMIT;
	      if(++i >= count)
		ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	    }
	  else
	    if(!strncasecmp(args[i], "lifetime", 4))
	      {
		wrq.u.retry.flags &= ~IW_RETRY_LIMIT;
		wrq.u.retry.flags |= IW_RETRY_LIFETIME;
		if(++i >= count)
		  ABORT_ARG_NUM("Set Retry Limit", SIOCSIWRETRY);
	      }

	  /* Is there any value to grab ? */
	  if(sscanf(args[i], "%lg", &(temp)) == 1)
	    {
	      /* Limit is absolute, on the other hand lifetime is seconds */
	      if(!(wrq.u.retry.flags & IW_RETRY_LIMIT))
		{
		  /* Normalise lifetime */
		  temp *= MEGA;	/* default = s */
		  if(index(args[i], 'u')) temp /= MEGA;
		  if(index(args[i], 'm')) temp /= KILO;
		}
	      wrq.u.retry.value = (long) temp;
	      ++i;
	      gotone = 1;
	    }

	  if(!gotone)
	    ABORT_ARG_TYPE("Set Retry Limit", SIOCSIWRETRY, args[i]);
	  --i;

	  IW_SET_EXT_ERR(skfd, ifname, SIOCSIWRETRY, &wrq,
			 "Set Retry Limit");
	  continue;
	}

#endif	/* WIRELESS_EXT > 10 */

      /* ---------- Other ---------- */
      /* Here we have an unrecognised arg... */
      fprintf(stderr, "Error : unrecognised wireless request \"%s\"\n",
	      args[i]);
      return(-1);
    }		/* for(index ... */
  return(0);
}
Ejemplo n.º 3
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[8192];	/* 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 now so that sub-ioctl takes precedence, 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 alignment issues) */
      offset = sizeof(__u32);
      /* Use real ioctl definition from now on */
      k = j;

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

  /* 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(strchr(args[i], 'G')) freq *= GIGA;
	    if(strchr(args[i], 'M')) freq *= MEGA;
	    if(strchr(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 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 needs exactly %d argument(s)...\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
	{
	  /* Third case : args won't fit in wrq, or variable number of args */
	  wrq.u.data.pointer = (caddr_t) buffer;
	  wrq.u.data.flags = subcmd;
	}
    }

#if 1
	if((priv[k].cmd == 0x8BED) && (wrq.u.data.pointer == (caddr_t) buffer))
	    wrq.u.data.length = sizeof(buffer);
#endif  
  /* 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.16s  %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[n] = '\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_saether_ntop(hwa, scratch));
	      }
	  }
	  break;

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

  return(0);
}
Ejemplo n.º 4
0
/*
 * Set list of addresses specified on command line in the driver.
 */
static int
set_spy_info(int		skfd,		/* The socket */
	     char *		ifname,		/* Dev name */
	     char *		args[],		/* Command line args */
	     int		count)		/* Args count */
{
  struct iwreq		wrq;
  int			i;
  int			nbr;		/* Number of valid addresses */
  struct sockaddr	hw_address[IW_MAX_SPY];

  /* Read command line */
  i = 0;	/* first arg to read */
  nbr = 0;	/* Number of args read so far */

  /* "off" : disable functionality (set 0 addresses) */
  if(!strcmp(args[0], "off"))
    i = 1;	/* skip the "off" */
  else
    {
      /* "+" : add all addresses already in the driver */
      if(!strcmp(args[0], "+"))
	{
	  char	buffer[(sizeof(struct iw_quality) +
			sizeof(struct sockaddr)) * IW_MAX_SPY];

	  /* Check if we have valid mac address type */
	  if(iw_check_mac_addr_type(skfd, ifname) < 0)
	    {
	      fprintf(stderr, "%-8.16s  Interface doesn't support MAC addresses\n", ifname);
	      return(-1);
	    }

	  wrq.u.data.pointer = (caddr_t) buffer;
	  wrq.u.data.length = IW_MAX_SPY;
	  wrq.u.data.flags = 0;
	  if(iw_get_ext(skfd, ifname, SIOCGIWSPY, &wrq) < 0)
	    {
	      fprintf(stderr, "Interface doesn't accept reading addresses...\n");
	      fprintf(stderr, "SIOCGIWSPY: %s\n", strerror(errno));
	      return(-1);
	    }

	  /* Copy old addresses */
	  nbr = wrq.u.data.length;
	  memcpy(hw_address, buffer, nbr * sizeof(struct sockaddr));

	  i = 1;	/* skip the "+" */
	}

      /* Read other args on command line */
      while((i < count) && (nbr < IW_MAX_SPY))
	{
	  /* Get the address and check if the interface supports it */
	  if(iw_in_addr(skfd, ifname, args[i++], &(hw_address[nbr])) < 0)
	    continue;
	  nbr++;
	}

      /* Check the number of addresses */
      if(nbr == 0)
	{
	  fprintf(stderr, "No valid addresses found : exiting...\n");
	  return(-1);
	}
    }

  /* Check if there is some remaining arguments */
  if(i < count)
    {
      fprintf(stderr, "Got only the first %d arguments, remaining discarded\n", i);
    }

  /* Time to do send addresses to the driver */
  wrq.u.data.pointer = (caddr_t) hw_address;
  wrq.u.data.length = nbr;
  wrq.u.data.flags = 0;
  if(iw_set_ext(skfd, ifname, SIOCSIWSPY, &wrq) < 0)
    {
      fprintf(stderr, "Interface doesn't accept addresses...\n");
      fprintf(stderr, "SIOCSIWSPY: %s\n", strerror(errno));
      return(-1);
    }

  return(0);
}