iwconfig 소스
*
* Wireless Tools
*
* Jean II - HPLB 97->99 - HPL 99->04
*
* Main code for "iwconfig". This is the generic tool for most
* manipulations...
* You need to link this code against "iwlib.c" and "-lm".
*
* This file is released under the GPL license.
* Copyright (c) 1997-2004 Jean Tourrilhes <[email protected]>
*/
#include "iwlib.h" /* Header */
/************************* MISC SUBROUTINES **************************/
/*------------------------------------------------------------------*/
/*
* Print usage string
*/
static void
iw_usage(void)
{
fprintf(stderr, "Usage: iwconfig interface [essid {NN|on|off}]n");
fprintf(stderr, " [nwid {NN|on|off}]n");
fprintf(stderr, " [mode {managed|ad-hoc|...}n");
fprintf(stderr, " [freq N.NNNN[k|M|G]]n");
fprintf(stderr, " [channel N]n");
fprintf(stderr, " [ap {N|off|auto}]n");
fprintf(stderr, " [sens N]n");
fprintf(stderr, " [nick N]n");
fprintf(stderr, " [rate {N|auto|fixed}]n");
fprintf(stderr, " [rts {N|auto|fixed|off}]n");
fprintf(stderr, " [frag {N|auto|fixed|off}]n");
fprintf(stderr, " [enc {NNNN-NNNN|off}]n");
fprintf(stderr, " [power {period N|timeout N}]n");
fprintf(stderr, " [txpower N {mW|dBm}]n");
fprintf(stderr, " [commit]n");
fprintf(stderr, " Check man pages for more details.nn");
}
/************************* DISPLAY ROUTINES **************************/
/*------------------------------------------------------------------*/
/*
* Get wireless informations & config from the device driver
* We will call all the classical wireless ioctl on the driver through
* the socket to know what is supported and to get the settings...
*/
static int
get_info(int skfd,
char * ifname,
struct wireless_info * info)
{
struct iwreq wrq;
memset((char *) info, 0, sizeof(struct wireless_info));
/* Get basic information */
if(iw_get_basic_config(skfd, ifname, &(info->b)) < 0)
{
/* If no wireless name : no wireless extensions */
/* But let's check if the interface exists at all */
struct ifreq ifr;
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
return(-ENODEV);
else
return(-ENOTSUP);
}
/* Get ranges */
if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
info->has_range = 1;
/* Get sensitivity */
if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
{
info->has_sens = 1;
memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
}
/* Get AP address */
if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
{
info->has_ap_addr = 1;
memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
}
/* Get NickName */
wrq.u.essid.pointer = (caddr_t) info->nickname;
wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
wrq.u.essid.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
if(wrq.u.data.length > 1)
info->has_nickname = 1;
/* Get bit rate */
if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
{
info->has_bitrate = 1;
memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
}
/* Get RTS threshold */
if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
{
info->has_rts = 1;
memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
}
/* Get fragmentation threshold */
if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
{
info->has_frag = 1;
memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
}
/* Get Power Management settings */
wrq.u.power.flags = 0;
if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
{
info->has_power = 1;
memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
}
if((info->has_range) && (info->range.we_version_compiled > 9))
{
/* Get Transmit Power */
if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
{
info->has_txpower = 1;
memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
}
}
if((info->has_range) && (info->range.we_version_compiled > 10))
{
/* Get retry limit/lifetime */
if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
{
info->has_retry = 1;
memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
}
}
/* Get stats */
if(iw_get_stats(skfd, ifname, &(info->stats),
&info->range, info->has_range) >= 0)
{
info->has_stats = 1;
}
return(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.16s %s ", ifname, info->b.name);
/* Display ESSID (extended network), if any */
if(info->b.has_essid)
{
if(info->b.essid_on)
{
/* Does it have an ESSID index ? */
if((info->b.essid_on & IW_ENCODE_INDEX) > 1)
printf("ESSID:"%s" [%d] ", info->b.essid,
(info->b.essid_on & IW_ENCODE_INDEX));
else
printf("ESSID:"%s" ", info->b.essid);
}
else
printf("ESSID:off/any ");
}
/* Display NickName (station name), if any */
if(info->has_nickname)
printf("Nickname:"%s"", info->nickname);
/* Formatting */
if(info->b.has_essid || info->has_nickname)
{
printf("n ");
tokens = 0;
}
/* Display Network ID */
if(info->b.has_nwid)
{
/* Note : should display proper number of digit according to info
* in range structure */
if(info->b.nwid.disabled)
printf("NWID:off/any ");
else
printf("NWID:%X ", info->b.nwid.value);
tokens +=2;
}
/* Display the current mode of operation */
if(info->b.has_mode)
{
printf("Mode:%s ", iw_operation_mode[info->b.mode]);
tokens +=3;
}
/* Display frequency / channel */
if(info->b.has_freq)
{
double freq = info->b.freq; /* Frequency/channel */
int channel = -1; /* Converted to channel */
/* Some driver insist of returning channel instead of frequency.
* This fixes them up. Note that, driver should still return
* frequency, because other tools depend on it. */
if(info->has_range && (freq < KILO))
channel = iw_channel_to_freq((int) freq, &freq, &info->range);
/* Display */
iw_print_freq(buffer, sizeof(buffer), freq, -1, info->b.freq_flags);
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->b.has_mode) && (info->b.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, sizeof(buffer), info->bitrate.value);
printf("Bit Rate%c%s ", (info->bitrate.fixed ? '=' : ':'), buffer);
}
/* Display the Transmit Power */
if(info->has_txpower)
{
/* A bit of clever formatting */
if(tokens > 11)
{
printf("n ");
tokens = 0;
}
tokens +=3;
/* Display it */
iw_print_txpower(buffer, sizeof(buffer), &info->txpower);
printf("Tx-Power%c%s ", (info->txpower.fixed ? '=' : ':'), buffer);
}
/* 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;
/* 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, sizeof(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 */
}
/* 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->b.has_key)
{
printf("Encryption key:");
if((info->b.key_flags & IW_ENCODE_DISABLED) || (info->b.key_size == 0))
printf("offn ");
else
{
/* Display the key */
iw_print_key(buffer, sizeof(buffer),
info->b.key, info->b.key_size, info->b.key_flags);
printf("%s", buffer);
/* Other info... */
if((info->b.key_flags & IW_ENCODE_INDEX) > 1)
printf(" [%d]", info->b.key_flags & IW_ENCODE_INDEX);
if(info->b.key_flags & IW_ENCODE_RESTRICTED)
printf(" Security mode:restricted");
if(info->b.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(":offn ");
else
{
/* Let's check the value and its type */
if(info->power.flags & IW_POWER_TYPE)
{
iw_print_pm_value(buffer, sizeof(buffer),
info->power.value, info->power.flags);
printf("%s ", buffer);
}
/* Let's check the mode */
iw_print_pm_mode(buffer, sizeof(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)
{
iw_print_stats(buffer, sizeof(buffer),
&info->stats.qual, &info->range, info->has_range);
printf("Link %sn", buffer);
if(info->range.we_version_compiled > 11)
printf(" Rx invalid nwid:%d Rx invalid crypt:%d Rx invalid frag:%dn Tx excessive retries:%d Invalid misc:%d Missed beacon:%dn",
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
printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%dn",
info->stats.discard.nwid,
info->stats.discard.code,
info->stats.discard.misc);
}
printf("n");
}
/*------------------------------------------------------------------*/
/*
* Print on the screen in a neat fashion all the info we have collected
* on a device.
*/
static int
print_info(int skfd,
char * ifname,
char * args[],
int count)
{
struct wireless_info info;
int rc;
/* Avoid "Unused parameter" warning */
args = args; count = count;
rc = get_info(skfd, ifname, &info);
switch(rc)
{
case 0: /* Success */
/* Display it ! */
display_info(&info, ifname);
break;
case -ENOTSUP:
fprintf(stderr, "%-8.16s no wireless extensions.nn",
ifname);
break;
default:
fprintf(stderr, "%-8.16s %snn", ifname, strerror(-rc));
}
return(rc);
}
/************************* SETTING ROUTINES **************************/
/*------------------------------------------------------------------*/
/*
* Macro to handle errors when setting WE
* Print a nice error message and exit...
* We define them as macro so that "return" do the right thing.
* The "do {...} while(0)" is a standard trick
*/
#define ERR_SET_EXT(rname, request)
fprintf(stderr, "Error for wireless request "%s" (%X) :n",
rname, request)
#define ABORT_ARG_NUM(rname, request)
do {
ERR_SET_EXT(rname, request);
fprintf(stderr, " too few arguments.n");
return(-1);
} while(0)
#define ABORT_ARG_TYPE(rname, request, arg)
do {
ERR_SET_EXT(rname, request);
fprintf(stderr, " invalid argument "%s".n", arg);
return(-2);
} while(0)
#define ABORT_ARG_SIZE(rname, request, max)
do {
ERR_SET_EXT(rname, request);
fprintf(stderr, " argument too big (max %d)n", max);
return(-3);
} while(0)
/*------------------------------------------------------------------*/
/*
* Wrapper to push some Wireless Parameter in the driver
* Use standard wrapper and add pretty error message if fail...
*/
#define IW_SET_EXT_ERR(skfd, ifname, request, wrq, rname)
do {
if(iw_set_ext(skfd, ifname, request, wrq) < 0) {
ERR_SET_EXT(rname, request);
fprintf(stderr, " SET failed on device %-1.16s ; %s.n",
ifname, strerror(errno));
return(-5);
} } while(0)
/*------------------------------------------------------------------*/
/*
* Wrapper to extract some Wireless Parameter out of the driver
* Use standard wrapper and add pretty error message if fail...
*/
#define IW_GET_EXT_ERR(skfd, ifname, request, wrq, rname)
do {
if(iw_get_ext(skfd, ifname, request, wrq) < 0) {
ERR_SET_EXT(rname, request);
fprintf(stderr, " GET failed on device %-1.16s ; %s.n",
ifname, strerror(errno));
return(-6);
} } while(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(!strcasecmp(args[i], "auto"))
{
wrq.u.freq.m = -1;
wrq.u.freq.e = 0;
wrq.u.freq.flags = 0;
}
else
{
if(!strcasecmp(args[i], "fixed"))
{
/* Get old bitrate */
IW_GET_EXT_ERR(skfd, ifname, SIOCGIWFREQ, &wrq,
"Set Bit Rate");
wrq.u.freq.flags = IW_FREQ_FIXED;
}
else /* Should be a numeric value */
{
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));
wrq.u.freq.flags = IW_FREQ_FIXED;
/* Check for an additional argument */
if(((i+1) < count) &&
(!strcasecmp(args[i+1], "auto")))
{
wrq.u.freq.flags = 0;
++i;
}
if(((i+1) < count) &&
(!strcasecmp(args[i+1], "fixed")))
{
wrq.u.freq.flags = IW_FREQ_FIXED;
++i;
}
}
}
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((i < count) && (!strncasecmp(args[i], "temporary", 4)))
{
wrq.u.data.flags |= IW_ENCODE_TEMP;
++i;
gotone++;
}
}
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] = '';
}
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;
}
/* ---------- 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.txpower.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], "on"))
{
/* Get old tx-power */
IW_GET_EXT_ERR(skfd, ifname, SIOCGIWTXPOW, &wrq,
"Set Tx Power");
wrq.u.txpower.disabled = 0;
}
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;
wrq.u.txpower.disabled = 0;
}
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_RELATIVE)
{
/* Can't convert */
if(ismwatt)
ABORT_ARG_TYPE("Set Tx Power",
SIOCSIWTXPOW,
args[i]);
}
else
if(range.txpower_capa & IW_TXPOW_MWATT)
{
if(!ismwatt)
power = iw_dbm2mwatt(power);
wrq.u.txpower.flags = IW_TXPOW_MWATT;
}
else
{
if(ismwatt)
power = iw_mwatt2dbm(power);
wrq.u.txpower.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;
}
/* ---------- 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;
}
/* ---------- Other ---------- */
/* Here we have an unrecognised arg... */
fprintf(stderr, "Error : unrecognised wireless request "%s"n",
args[i]);
return(-1);
} /* for(index ... */
return(0);
}
/******************************* MAIN ********************************/
/*------------------------------------------------------------------*/
/*
* The main !
*/
int
main(int argc,
char ** argv)
{
int skfd; /* generic raw socket desc. */
int goterr = 0;
/* Create a channel to the NET kernel. */
if((skfd = iw_sockets_open()) < 0)
{
perror("socket");
exit(-1);
}
/* No argument : show the list of all device + info */
if(argc == 1)
iw_enum_devices(skfd, &print_info, NULL, 0);
else
/* Special case for help... */
if((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "--help")))
iw_usage();
else
/* Special case for version... */
if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))
goterr = iw_print_version_info("iwconfig");
else
/* The device name must be the first argument */
if(argc == 2)
print_info(skfd, argv[1], NULL, 0);
else
/* The other args on the line specify options to be set... */
goterr = set_info(skfd, argv + 2, argc - 2, argv[1]);
/* Close the socket. */
iw_sockets_close(skfd);
return(goterr);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.