Ejemplo n.º 1
0
int make_connection(IP4Address ip, uint16_t port)
{
    struct sockaddr_in server_address;
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1)
    {
        perror("socket");
        return -1;
    }
    if (fd_max <= fd)
        fd_max = fd + 1;

    const int yes = 1;
    /// Allow to bind() again after the server restarts.
    // Since the socket is still in the TIME_WAIT, there's a possibility
    // that formerly lost packets might be delivered and confuse the server.
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
    /// Send packets as soon as possible
    /// even if the kernel thinks there is too little for it to be worth it!
    // I'm not convinced this is a good idea; although in minimizes the
    // latency for an individual write, it increases traffic in general.
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof yes);

    server_address.sin_family = AF_INET;
    server_address.sin_addr = in_addr(ip);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#if __GNUC__ > 4 || __GNUC_MINOR__ >= 8
#pragma GCC diagnostic ignored "-Wuseless-cast"
#endif
    server_address.sin_port = htons(port);
#pragma GCC diagnostic pop

    fcntl(fd, F_SETFL, O_NONBLOCK);

    /// Errors not caught - we must not block
    /// Let the main select() loop detect when we know the state
    connect(fd, reinterpret_cast<struct sockaddr *>(&server_address),
             sizeof(struct sockaddr_in));

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
    FD_SET(fd, &readfds);
#pragma GCC diagnostic pop

    session[fd] = make_unique<socket_data>();
    session[fd]->rdata.new_(RFIFO_SIZE);
    session[fd]->wdata.new_(WFIFO_SIZE);

    session[fd]->max_rdata = RFIFO_SIZE;
    session[fd]->max_wdata = WFIFO_SIZE;
    session[fd]->func_recv = recv_to_fifo;
    session[fd]->func_send = send_from_fifo;
    session[fd]->func_parse = default_func_parse;
    session[fd]->created = TimeT::now();
    session[fd]->connected = 1;

    return fd;
}
Ejemplo n.º 2
0
BOOL S3PDBSocketPool::ShowAllClientInfo()
{
	if (IsLocked())
		return FALSE;
	Lock();
	BOOL b = FALSE;
	GatewayIDMap::iterator i = m_clientIDs.begin();
	int n = 0;
	while (i != m_clientIDs.end())
	{
		KGatewayDataProcess* p = i->second;
		if (p)
		{
			in_addr add;
			add.s_addr = p->m_Address;
			gTrace("Client %d: %s(%s)", n, p->m_ServerName.c_str(), inet_ntoa(in_addr(add))); 
		}
		i++;
		n++;
	}
	b = TRUE;
	Unlock();
	return b;
}
Ejemplo n.º 3
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;

  /* Set dev name */
  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);

  /* if nothing after the device name */
  if(count<1)
    iw_usage();

  /* The other args on the line specify options to be set... */
  for(i = 0; i < count; i++)
    {
      /* ---------- Set network ID ---------- */
      if((!strcasecmp(args[i], "nwid")) ||
	 (!strcasecmp(args[i], "domain")))
	{
	  i++;
	  if(i >= count)
	    iw_usage();
	  if((!strcasecmp(args[i], "off")) ||
	     (!strcasecmp(args[i], "any")))
	    wrq.u.nwid.disabled = 1;
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old nwid */
		if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
		  {
		    fprintf(stderr, "SIOCGIWNWID: %s\n", strerror(errno));
		    return(-1);
		  }
		strcpy(wrq.ifr_name, ifname);
		wrq.u.nwid.disabled = 0;
	      }
	    else
	      if(sscanf(args[i], "%lX", (unsigned long *) &(wrq.u.nwid.value))
		 != 1)
		iw_usage();
	      else
		wrq.u.nwid.disabled = 0;
	  wrq.u.nwid.fixed = 1;

	  if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

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

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

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

	  if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

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

	  if(ioctl(skfd, SIOCSIWSENS, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWSENS: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

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

	  if(++i >= count)
	    iw_usage();

	  if(!strcasecmp(args[i], "on"))
	    {
	      /* Get old encryption information */
	      wrq.u.data.pointer = (caddr_t) key;
	      wrq.u.data.length = 0;
	      wrq.u.data.flags = 0;
	      if(ioctl(skfd, SIOCGIWENCODE, &wrq) < 0)
		{
		  fprintf(stderr, "SIOCGIWENCODE: %s\n", strerror(errno));
		  return(-1);
		}
	      strcpy(wrq.ifr_name, ifname);
	      wrq.u.data.flags &= ~IW_ENCODE_DISABLED;	/* Enable */
	    }
	  else
	    {
	      char *	buff;
	      char *	p;
	      int		temp;
	      int		k = 0;
	      int		gotone = 1;

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

	      /* -- Check for the key -- */
	      if(!strncmp(args[i], "s:", 2))
		{
		  /* First case : as an ASCII string */
		  wrq.u.data.length = strlen(args[i] + 2);
		  if(wrq.u.data.length > IW_ENCODING_TOKEN_MAX)
		    wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
		  strncpy(key, args[i] + 2, wrq.u.data.length);
		  wrq.u.data.pointer = (caddr_t) key;
		  ++i;
		  gotone = 1;
		}
	      else
		{
		  /* Second case : has hexadecimal digits */
		  p = buff = malloc(strlen(args[i]) + 1);
		  strcpy(buff, args[i]);

		  p = strtok(buff, "-:;.,");
		  while(p != (char *) NULL)
		    {
		      if(sscanf(p, "%2X", &temp) != 1)
			{
			  gotone = 0;
			  break;
			}
		      key[k++] = (unsigned char) (temp & 0xFF);
		      if(strlen(p) > 2)	/* Token not finished yet */
			p += 2;
		      else
			p = strtok((char *) NULL, "-:;.,");
		    }
		  free(buff);

		  if(gotone)
		    {
		      ++i;
		      wrq.u.data.length = k;
		      wrq.u.data.pointer = (caddr_t) key;
		    }
		}

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

	      /* -- Check the various flags -- */
	      if(i < count)
		{
		  if(!strcasecmp(args[i], "off"))
		    wrq.u.data.flags |= IW_ENCODE_DISABLED;
		  if(!strcasecmp(args[i], "open"))
		    wrq.u.data.flags |= IW_ENCODE_OPEN;
		  if(!strncasecmp(args[i], "restricted", 5))
		    wrq.u.data.flags |= IW_ENCODE_RESTRICTED;
		  if(wrq.u.data.flags & IW_ENCODE_FLAGS)
		    {
		      ++i;
		      gotone = 1;
		    }
		}

	      if(!gotone)
		iw_usage();
	      --i;
	    }

	  if(ioctl(skfd, SIOCSIWENCODE, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWENCODE(%d): %s\n",
		      errno, strerror(errno));
	      return(-1);
	    }
	  continue;
  	}

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

	  i++;
	  if(i >= count)
	    iw_usage();
	  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 = 0;
		wrq.u.essid.flags = 0;
		if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
		  {
		    fprintf(stderr, "SIOCGIWESSID: %s\n", strerror(errno));
		    return(-1);
		  }
		strcpy(wrq.ifr_name, ifname);
		wrq.u.essid.flags = 1;
	      }
	    else
	      if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
		{
		  fprintf(stderr, "ESSID too long (max %d): ``%s''\n",
			  IW_ESSID_MAX_SIZE, args[i]);
		  iw_usage();
		}
	      else
		{
		  int		temp;

		  wrq.u.essid.flags = 1;
		  strcpy(essid, args[i]);

		  /* Check for ESSID index */
		  if(((i+1) < count) &&
		     (sscanf(args[i+1], "[%d]", &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;
	  if(ioctl(skfd, SIOCSIWESSID, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWESSID: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

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

	  /* Check if we have valid address types */
	  if(check_addr_type(skfd, ifname) < 0)
	    {
	      fprintf(stderr, "%-8.8s  Interface doesn't support MAC & IP addresses\n", ifname);
	      return(-1);
	    }

	  /* Get the address */
	  if(in_addr(skfd, ifname, args[i++], &(wrq.u.ap_addr)) < 0)
	    iw_usage();

	  if(ioctl(skfd, SIOCSIWAP, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWAP: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

      /* ---------- Set NickName ---------- */
      if(!strncmp(args[i], "nick", 4))
	{
	  i++;
	  if(i >= count)
	    iw_usage();
	  if(strlen(args[i]) > IW_ESSID_MAX_SIZE)
	    {
	      fprintf(stderr, "Name too long (max %d) : ``%s''\n",
		      IW_ESSID_MAX_SIZE, args[i]);
	      iw_usage();
	    }

	  wrq.u.essid.pointer = (caddr_t) args[i];
	  wrq.u.essid.length = strlen(args[i]) + 1;
	  if(ioctl(skfd, SIOCSIWNICKN, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWNICKN: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

      /* ---------- Set Bit-Rate ---------- */
      if((!strncmp(args[i], "bit", 3)) ||
	 (!strcmp(args[i], "rate")))
	{
	  if(++i >= count)
	    iw_usage();
	  if(!strcasecmp(args[i], "auto"))
	    {
	      wrq.u.bitrate.value = -1;
	      wrq.u.bitrate.fixed = 0;
	    }
	  else
	    {
	      if(!strcasecmp(args[i], "fixed"))
		{
		  /* Get old bitrate */
		  if(ioctl(skfd, SIOCGIWRATE, &wrq) < 0)
		    {
		      fprintf(stderr, "SIOCGIWRATE: %s\n", strerror(errno));
		      return(-1);
		    }
		  strcpy(wrq.ifr_name, ifname);
		  wrq.u.bitrate.fixed = 1;
		}
	      else			/* Should be a numeric value */
		{
		  double		brate;

		  if(sscanf(args[i], "%lg", &(brate)) != 1)
		    iw_usage();
		  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;
		    }
		}
	    }

	  if(ioctl(skfd, SIOCSIWRATE, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWRATE: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

      /* ---------- Set RTS threshold ---------- */
      if(!strncasecmp(args[i], "rts", 3))
	{
	  i++;
	  if(i >= count)
	    iw_usage();
	  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 */
		    if(ioctl(skfd, SIOCGIWRTS, &wrq) < 0)
		      {
			fprintf(stderr, "SIOCGIWRTS: %s\n", strerror(errno));
			return(-1);
		      }
		    strcpy(wrq.ifr_name, ifname);
		    wrq.u.rts.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.rts.value))
		     != 1)
		    iw_usage();
	    }

	  if(ioctl(skfd, SIOCSIWRTS, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWRTS: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

      /* ---------- Set fragmentation threshold ---------- */
      if(!strncmp(args[i], "frag", 4))
	{
	  i++;
	  if(i >= count)
	    iw_usage();
	  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 */
		    if(ioctl(skfd, SIOCGIWFRAG, &wrq) < 0)
		      {
			fprintf(stderr, "SIOCGIWFRAG: %s\n", strerror(errno));
			return(-1);
		      }
		    strcpy(wrq.ifr_name, ifname);
		    wrq.u.frag.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  if(sscanf(args[i], "%ld", (unsigned long *) &(wrq.u.frag.value))
		     != 1)
		    iw_usage();
	    }

	  if(ioctl(skfd, SIOCSIWFRAG, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWFRAG: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

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

	  i++;
	  if(i >= count)
	    iw_usage();

	  if(sscanf(args[i], "%d", &k) != 1)
	    {
	      k = 0;
	      while(k < 6 && strncasecmp(args[i], operation_mode[k], 3))
		k++;
	    }
	  if((k > 5) || (k < 0))
	    iw_usage();

	  wrq.u.mode = k;
	  if(ioctl(skfd, SIOCSIWMODE, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWMODE: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}

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

	  if(!strcasecmp(args[i], "off"))
	    wrq.u.power.disabled = 1;	/* i.e. max size */
	  else
	    if(!strcasecmp(args[i], "on"))
	      {
		/* Get old Power info */
		if(ioctl(skfd, SIOCGIWPOWER, &wrq) < 0)
		  {
		    fprintf(stderr, "SIOCGIWPOWER: %s\n", strerror(errno));
		    return(-1);
		  }
		strcpy(wrq.ifr_name, ifname);
		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)
		      iw_usage();
		  }
		else
		  if(!strcasecmp(args[i], "max"))
		    {
		      wrq.u.power.flags |= IW_POWER_MAX;
		      if(++i >= count)
			iw_usage();
		    }

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

		/* 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)
		  iw_usage();
		--i;
	      }

	  if(ioctl(skfd, SIOCSIWPOWER, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWPOWER(%d): %s\n",
		      errno, strerror(errno));
	      return(-1);
	    }
	  continue;
  	}

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

	  if(++i >= count)
	    iw_usage();

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

	  /* Prepare the request */
	  strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
	  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 */
		    if(ioctl(skfd, SIOCGIWTXPOW, &wrq) < 0)
		      {
			fprintf(stderr, "SIOCGIWTXPOW: %s\n", strerror(errno));
			return(-1);
		      }
		    strcpy(wrq.ifr_name, ifname);
		    wrq.u.txpower.fixed = 1;
		  }
		else			/* Should be a numeric value */
		  {
		    int		power;
		    int		ismwatt = 0;

		    /* Get the value */
		    if(sscanf(args[i], "%ld",
			      (unsigned long *) &(power)) != 1)
		      iw_usage();

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

		    /* Convert */
		    if(!ismwatt && (range.txpower_capa & IW_TXPOW_MWATT))
		      {
			power = dbm2mwatt(power);
			wrq.u.data.flags = IW_TXPOW_MWATT;
		      }
		    if(ismwatt && !(range.txpower_capa & IW_TXPOW_MWATT))
		      power = mwatt2dbm(power);
		    wrq.u.bitrate.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;
		      }
		  }
	      }

	  if(ioctl(skfd, SIOCSIWTXPOW, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWTXPOW: %s\n", strerror(errno));
	      return(-1);
	    }
	  continue;
	}
#endif

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

	  if(++i >= count)
	    iw_usage();

	  /* 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)
		iw_usage();
	    }
	  else
	    if(!strcasecmp(args[i], "max"))
	      {
		wrq.u.retry.flags |= IW_RETRY_MAX;
		if(++i >= count)
		  iw_usage();
	      }

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

	  /* 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)
	    iw_usage();
	  --i;

	  if(ioctl(skfd, SIOCSIWRETRY, &wrq) < 0)
	    {
	      fprintf(stderr, "SIOCSIWRETRY(%d): %s\n",
		      errno, strerror(errno));
	      return(-1);
	    }
	  continue;
	}

#endif	/* WIRELESS_EXT > 10 */

      /* ---------- Other ---------- */
      /* Here we have an unrecognised arg... */
      fprintf(stderr, "Invalid argument : %s\n", args[i]);
      iw_usage();
      return(-1);
    }		/* for(index ... */
  return(0);
}