iwpriv是Wireless Extensions 操作的特定驱动。通过iwpriv,可以得到AP的一些参数设置,也可以设置自己的WIFI参数。

[root@root- /]#iwpriv
wlan0     Available private ioctls :extscan          (8BFA) : set   0 int   & get   2 charhostcmd          (8BE4) : set 2047 byte  & get 2047 bytearpfilter        (8BE6) : set 2047 byte  & get 2047 byteregrdwr          (8BE3) : set 256 char  & get 256 charsdcmd52rw        (8BFE) : set   7 byte  & get   7 bytesdcmd53rw        (8BFF) : set   0 char  & get   0 charsetgetconf       (8BEA) : set 2000 byte  & get 2000 bytegetcis           (8BE1) : set   0       & get 512 bytescantype         (8BEB) : set   8 char  & get   8 chardeauth           (0001) : set   1 addr  & get   0getNF            (0001) : set   1 int   & get   1 intgetRSSI          (0002) : set   1 int   & get   1 intbgscan           (0004) : set   1 int   & get   1 intenable11d        (0005) : set   1 int   & get   1 intadhocgrate       (0006) : set   1 int   & get   1 intsdioclock        (0007) : set   1 int   & get   1 intwmm              (0008) : set   1 int   & get   1 intuapsdnullgen     (000A) : set   1 int   & get   1 intsetcoalescing    (000B) : set   1 int   & get   1 intadhocgprot       (000C) : set   1 int   & get   1 intdisable_chsw     (000F) : set   1 int   & get   1 intsetpowercons     (0001) : set   1 int   & get   1 intwmm_qosinfo      (0002) : set   1 int   & get   1 intlolisteninter    (0003) : set   1 int   & get   1 intpsnullinterval   (0005) : set   1 int   & get   1 intbcnmisto         (0006) : set   1 int   & get   1 intldocfg           (0008) : set   1 int   & get   1 intrtsctsctrl       (000F) : set   1 int   & get   1 intmoduletype       (000B) : set   1 int   & get   1 intautodeepsleep    (000C) : set   1 int   & get   1 intenhanceps        (000D) : set   1 int   & get   1 intwakeupmt         (000E) : set   1 int   & get   1 intsetrxant         (0001) : set   1 int   & get   0settxant         (0002) : set   1 int   & get   0authalgs         (0004) : set   1 int   & get   0encryptionmode   (0005) : set   1 int   & get   0setregioncode    (0006) : set   1 int   & get   0setlisteninter   (0007) : set   1 int   & get   0setmultipledtim  (0008) : set   1 int   & get   0setbcnavg        (0009) : set   1 int   & get   0setdataavg       (000A) : set   1 int   & get   0associate        (000B) : set   1 int   & get   0getregioncode    (0001) : set   0       & get   1 intgetlisteninter   (0002) : set   0       & get   1 intgetmultipledtim  (0003) : set   0       & get   1 intgettxrate        (0004) : set   0       & get   1 intgetbcnavg        (0005) : set   0       & get   1 intgetdataavg       (0006) : set   0       & get   1 intgetauthtype      (0007) : set   0       & get   1 intgetrsnmode       (0008) : set   0       & get   1 intact_paircipher   (0009) : set   0       & get   1 intact_groupcipher  (000A) : set   0       & get   1 intgetdtim          (000B) : set   0       & get   1 intgetrxant         (0001) : set   0       & get  12 chargettxant         (0002) : set   0       & get  12 chargettsf           (0003) : set   0       & get  12 charwpssession       (0004) : set   0       & get  12 chardeepsleep        (8BFB) : set   1 char  & get   6 charadhocstop        (0004) : set   0       & get   0radioon          (0001) : set   0       & get   0radiooff         (0002) : set   0       & get   0rmaeskey         (0003) : set   0       & get   0crypto_test      (0006) : set   0       & get   0reasso-on        (0007) : set   0       & get   0reasso-off       (0008) : set   0       & get   0wlanidle-on      (0009) : set   0       & get   0wlanidle-off     (000A) : set   0       & get   0softreset        (000C) : set   0       & get   0sleepparams      (0002) : set  64 char  & get  64 charrequesttpc       (0004) : set  64 char  & get  64 charpowercap         (0005) : set  64 char  & get  64 charmeasreq          (000C) : set  64 char  & get  64 charbca-ts           (0003) : set  64 char  & get  64 charscanmode         (0006) : set  64 char  & get  64 chargetadhocstatus   (0009) : set  64 char  & get  64 charsetgenie         (000A) : set  64 char  & get  64 chargetgenie         (000B) : set  64 char  & get  64 charqstatus          (000D) : set  64 char  & get  64 charts_status        (000E) : set  64 char  & get  64 charsetaeskey        (0001) : set  32 char  & get   0getaeskey        (0001) : set   1 int   & get 128 charversion          (0002) : set   1 int   & get 128 charverext           (0003) : set   1 int   & get 128 charsetwpaie         (8BE0) : set  24 char  & get   0setband          (0001) : set  10 char  & get   0setadhocch       (0002) : set  10 char  & get   0chanswann        (0003) : set  10 char  & get   0getband          (0001) : set   0       & get  10 chargetadhocch       (0002) : set   0       & get  10 chargetlog           (8BE9) : set   0       & get 512 chartpccfg           (0001) : set  16 int   & get  16 intscanprobes       (0006) : set  16 int   & get  16 intledgpio          (0005) : set  16 int   & get  16 intsleeppd          (0007) : set  16 int   & get  16 intrateadapt        (0008) : set  16 int   & get  16 intgetSNR           (0009) : set  16 int   & get  16 intgetrate          (000A) : set  16 int   & get  16 intgetrxinfo        (000B) : set  16 int   & get  16 intatimwindow       (000C) : set  16 int   & get  16 intbcninterval      (000D) : set  16 int   & get  16 intsdiopullctrl     (000E) : set  16 int   & get  16 intscantime         (000F) : set  16 int   & get  16 intsysclock         (0010) : set  16 int   & get  16 inttxcontrol        (0012) : set  16 int   & get  16 inthscfg            (0014) : set  16 int   & get  16 inthssetpara        (0015) : set  16 int   & get  16 intinactoext        (0016) : set  16 int   & get  16 intdbgscfg          (0017) : set  16 int   & get  16 intdrvdbg           (0018) : set  16 int   & get  16 intdrvdelaymax      (001A) : set  16 int   & get  16 intintfctrl         (001B) : set  16 int   & get  16 intsetquietie       (001C) : set  16 int   & get  16 intctspowerctrl     (001E) : set  16 int   & get  16 intpsmode           (001F) : set  16 int   & get  16 intsetuserscan      (0001) : set 2000 byte  & get 2000 bytegetscantable     (0002) : set 2000 byte  & get 2000 bytesetmrvltlv       (0003) : set 2000 byte  & get 2000 bytegetassocrsp      (0004) : set 2000 byte  & get 2000 byteaddts            (0005) : set 2000 byte  & get 2000 bytedelts            (0006) : set 2000 byte  & get 2000 byteqconfig          (0007) : set 2000 byte  & get 2000 byteqstats           (0008) : set 2000 byte  & get 2000 bytetxpktstats       (000C) : set 2000 byte  & get 2000 bytegetcfptable      (0009) : set 2000 byte  & get 2000 bytemefcfg           (000A) : set 2000 byte  & get 2000 bytegetmem           (000B) : set 2000 byte  & get 2000 byte

iwpriv源码中的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");return(-1);}/* No argument : show the list of all devices + ioctl list */if(argc == 1)iw_enum_devices(skfd, &print_priv_info, NULL, 0);else/* Special cases take one... *//* All */if((!strncmp(argv[1], "-a", 2)) || (!strcmp(argv[1], "--all")))iw_enum_devices(skfd, &print_priv_all, NULL, 0);else/* Help */if((!strncmp(argv[1], "-h", 2)) || (!strcmp(argv[1], "--help")))iw_usage();else/* Version */if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))goterr = iw_print_version_info("iwpriv");else/* The device name must be the first argument *//* Name only : show for that device only */if(argc == 2)print_priv_info(skfd, argv[1], NULL, 0);else/* Special cases take two... *//* All */if((!strncmp(argv[2], "-a", 2)) ||(!strcmp(argv[2], "--all")))print_priv_all(skfd, argv[1], NULL, 0);else
#if 0/* Roaming */if(!strncmp(argv[2], "roam", 4))goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);else/* Port type */if(!strncmp(argv[2], "port", 4))goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);else
#endif/*-------------*//* Otherwise, it's a private ioctl */goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);/* Close the socket. */iw_sockets_close(skfd);return(goterr);
}

iw_enum_devices函数类似,调用了print_priv_info函数做参数。
iw_print_version_info函数,打印出了wireless的版本信息,wireless extension版本信息和接口驱动的版本信息。
print_priv_info函数,打印出通过ioctl获取的无线驱动中的设备具有的私有数据和信息。
print_priv_all函数,打印出通过GET ioctl获取的无线驱动中的设备具有的私有数据和信息。
set_private函数,通过ioctl来设定无线驱动中关于设备的私有配置和数据。

print_priv_info函数,内容如下:

/*------------------------------------------------------------------*/
/** Print on the screen in a neat fashion the list of private ioctls* for the device.*/
static int
print_priv_info(int     skfd,char *      ifname,char *      args[],int     count)
{int       k;iwprivargs *  priv;int       n;/* Avoid "Unused parameter" warning */args = args; count = count;/* Read the private ioctls */n = iw_get_priv_info(skfd, ifname, &priv);/* Is there any ? */if(n <= 0){/* Should I skip this message ? */fprintf(stderr, "%-8.16s  no private ioctls.\n\n",ifname);}else{printf("%-8.16s  Available private ioctls :\n", ifname);/* Print them all */for(k = 0; k < n; k++)if(priv[k].name[0] != '\0')printf("          %-16.16s (%.4X) : set %3d %s & get %3d %s\n",priv[k].name, priv[k].cmd,priv[k].set_args & IW_PRIV_SIZE_MASK,argtype[(priv[k].set_args & IW_PRIV_TYPE_MASK) >> 12],priv[k].get_args & IW_PRIV_SIZE_MASK,argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);printf("\n");}/* Cleanup */if(priv)free(priv);return(0);
}

使用了iw_get_priv_info函数获取数据然后打印输出。

iw_get_priv_info函数内容如下:


/*------------------------------------------------------------------*/
/** Get information about what private ioctls are supported by the driver** Note : there is one danger using this function. If it return 0, you* still need to free() the buffer. Beware.*/
int
iw_get_priv_info(int        skfd,const char *   ifname,iwprivargs **  ppriv)
{struct iwreq      wrq;iwprivargs *      priv = NULL;    /* Not allocated yet */int           maxpriv = 16;   /* Minimum for compatibility WE<13 */iwprivargs *      newpriv;/* Some driver may return a very large number of ioctls. Some* others a very small number. We now use a dynamic allocation* of the array to satisfy everybody. Of course, as we don't know* in advance the size of the array, we try various increasing* sizes. Jean II */do{/* (Re)allocate the buffer */newpriv = realloc(priv, maxpriv * sizeof(priv[0]));if(newpriv == NULL){fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__);break;}priv = newpriv;/* Ask the driver if it's large enough */wrq.u.data.pointer = (caddr_t) priv;wrq.u.data.length = maxpriv;wrq.u.data.flags = 0;if(iw_get_ext(skfd, ifname, SIOCGIWPRIV, &wrq) >= 0){/* Success. Pass the buffer by pointer */*ppriv = priv;/* Return the number of ioctls */
      return(wrq.u.data.length);}/* Only E2BIG means the buffer was too small, abort on other errors */if(errno != E2BIG){/* Most likely "not supported". Don't barf. */break;}/* Failed. We probably need a bigger buffer. Check if the kernel* gave us any hints. */if(wrq.u.data.length > maxpriv)maxpriv = wrq.u.data.length;elsemaxpriv *= 2;}while(maxpriv < 1000);/* Cleanup */if(priv)free(priv);*ppriv = NULL;
return(-1);
}

私有数据使用iwprivargs结构体,通过iw_get_ext函数和参数SIOCGIWPRIV和wrq,进行ioctl操作,获取私有数据。

iwprivargs是定义的iw_priv_args结构体,定义如下:

/** Private ioctl interface information*/struct  iw_priv_args
{__u32       cmd;        /* Number of the ioctl to issue */__u16       set_args;   /* Type and number of args */__u16       get_args;   /* Type and number of args */char        name[IFNAMSIZ]; /* Name of the extension */
};

iw_print_version_info函数内容如下;

/*------------------------------------------------------------------*/
/** Print the WE versions of the tools.*/
int
iw_print_version_info(const char *  toolname)
{int       skfd;           /* generic raw socket desc. */int       we_kernel_version;/* Create a channel to the NET kernel. */if((skfd = iw_sockets_open()) < 0){perror("socket");return -1;}/* Information about the tools themselves */if(toolname != NULL)printf("%-8.16s  Wireless-Tools version %d\n", toolname, WT_VERSION);printf("          Compatible with Wireless Extension v11 to v%d.\n\n",WE_MAX_VERSION);/* Get version from kernel */we_kernel_version = iw_get_kernel_we_version();/* Only version >= 16 can be verified, other are guessed */if(we_kernel_version > 15)printf("Kernel    Currently compiled with Wireless Extension v%d.\n\n",we_kernel_version);/* Version for each device */iw_enum_devices(skfd, &print_iface_version_info, NULL, 0);iw_sockets_close(skfd);return 0;
}

可以看到使用了print_iface_version_info函数来获取无线驱动接口的版本信息,内容如下:


/*------------------------------------------------------------------*/
/** Print the WE versions of the interface.*/
static int
print_iface_version_info(int    skfd,char * ifname,char * args[],     /* Command line args */int    count)      /* Args count */
{struct iwreq      wrq;char          buffer[sizeof(iwrange) * 2];    /* Large enough */struct iw_range * range;/* Avoid "Unused parameter" warning */args = args; count = count;/* If no wireless name : no wireless extensions.* This enable us to treat the SIOCGIWRANGE failure below properly. */if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
    return(-1);/* Cleanup */memset(buffer, 0, sizeof(buffer));wrq.u.data.pointer = (caddr_t) buffer;wrq.u.data.length = sizeof(buffer);wrq.u.data.flags = 0;if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0){/* Interface support WE (see above), but not IWRANGE */fprintf(stderr, "%-8.16s  Driver has no Wireless Extension version information.\n\n", ifname);
      return(0);}/* Copy stuff at the right place, ignore extra */range = (struct iw_range *) buffer;/* For new versions, we can check the version directly, for old versions* we use magic. 300 bytes is a also magic number, don't touch... */if(wrq.u.data.length >= 300){/* Version is always at the same offset, so it's ok */printf("%-8.16s  Recommend Wireless Extension v%d or later,\n",ifname, range->we_version_source);printf("          Currently compiled with Wireless Extension v%d.\n\n",range->we_version_compiled);}else{fprintf(stderr, "%-8.16s  Wireless Extension version too old.\n\n",ifname);}
return(0);
}

print_priv_all函数的内容如下:


/*------------------------------------------------------------------*/
/** Print on the screen in a neat fashion the list of private GET ioctl* data for the device and data returned by those.*/
static int
print_priv_all(int      skfd,char *       ifname,char *       args[],int      count)
{int       k;iwprivargs *  priv;int       n;/* Avoid "Unused parameter" warning */args = args; count = count;/* Read the private ioctls */n = iw_get_priv_info(skfd, ifname, &priv);/* Is there any ? */if(n <= 0){/* Should I skip this message ? */fprintf(stderr, "%-8.16s  no private ioctls.\n\n",ifname);}else{printf("%-8.16s  Available read-only private ioctl :\n", ifname);/* Print them all */for(k = 0; k < n; k++)/* We call all ioctls that don't have a null name, don't require* args and return some (avoid triggering "reset" commands) */if((priv[k].name[0] != '\0') && (priv[k].set_args == 0) &&(priv[k].get_args != 0))set_private_cmd(skfd, NULL, 0, ifname, priv[k].name,priv, n);printf("\n");}/* Cleanup */if(priv)free(priv);return(0);
}

print_priv_all函数与print_priv_info的不同之处是调用了set_private_cmd函数对接口执行了一个私有的获取命令,内容如下:

/*------------------------------------------------------------------*/
/** 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 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 0printf("<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;}}/* 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;}elsen = 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);elseif(freq >= MEGA)printf("%gM  ", freq / MEGA);elseprintf("%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);
}

iwpriv的设置通过set_private函数来实现,该函数的内容如下:


/*------------------------------------------------------------------*/
/** Execute a private command on the interface*/
static inline int
set_private(int     skfd,       /* Socket */char *  args[],     /* Command line args */int     count,      /* Args count */char *  ifname)     /* Dev name */
{iwprivargs *  priv;int       number;     /* Max of private ioctl */int       ret;/* Read the private ioctls */number = iw_get_priv_info(skfd, ifname, &priv);/* Is there any ? */if(number <= 0){/* Should I skip this message ? */fprintf(stderr, "%-8.16s  no private ioctls.\n\n",ifname);if(priv)free(priv);return(-1);}/* Do it */ret = set_private_cmd(skfd, args + 1, count - 1, ifname, args[0],priv, number);free(priv);return(ret);
}

set_private函数也是调用了set_private_cmd函数来执行ioctl的修改了无线设备驱动的私有配置数据。

wireless-tools源码分析-iwpriv相关推荐

  1. Spring Developer Tools 源码分析:二、类路径监控

    在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...

  2. kazoo源码分析:Zookeeper客户端start概述

    kazoo源码分析 kazoo-2.6.1 kazoo客户端 kazoo是一个由Python编写的zookeeper客户端,实现了zookeeper协议,从而提供了Python与zookeeper服务 ...

  3. kubeadm源码分析(内含kubernetes离线包,三步安装)

    k8s离线安装包 三步安装,简单到难以置信 kubeadm源码分析 说句实在话,kubeadm的代码写的真心一般,质量不是很高. 几个关键点来先说一下kubeadm干的几个核心的事: kubeadm ...

  4. 《深入理解Spark:核心思想与源码分析》——1.2节Spark初体验

    本节书摘来自华章社区<深入理解Spark:核心思想与源码分析>一书中的第1章,第1.2节Spark初体验,作者耿嘉安,更多章节内容可以访问云栖社区"华章社区"公众号查看 ...

  5. soundtouch源码分析__based on csdn :

    1. soundtouch介绍和相关资源 The SoundTouch Library Copyright © Olli Parviainen 2001-2014 SoundTouch is an o ...

  6. linux nDPI 协议检测 源码分析

    关于nDPI的基本功能就不在这介绍了,有兴趣了解的读者可以阅读官方的快速入门指南:https://github.com/ntop/nDPI/blob/dev/doc/nDPI_QuickStartGu ...

  7. java 源码分析_Java 源代码编译成 Class 文件的过程分析

    原标题:Java 源代码编译成 Class 文件的过程分析 在上篇文章< Java三种编译方式:前端编译 JIT编译 AOT编译 >中了解到了它们各有什么优点和缺点,以及前端编译+JIT编 ...

  8. 【Android 插件化】VirtualApp 源码分析 ( 添加应用源码分析 | LaunchpadAdapter 适配器 | 适配器添加元素 | PackageAppData 元素 )

    文章目录 一.添加应用源码分析 1.LaunchpadAdapter 适配器 2.适配器添加元素 3.PackageAppData 元素 一.添加应用源码分析 1.LaunchpadAdapter 适 ...

  9. zg手册 之 python2.7.7源码分析(1)-- python中的对象

    为什么80%的码农都做不了架构师?>>>    源代码主要目录结构 Demo: python 的示例程序 Doc: 文档 Grammar: 用BNF的语法定义了Python的全部语法 ...

最新文章

  1. 洛谷 - P1426 - 小鱼会有危险吗 - 模拟
  2. linux命令后面常见的/dev/null 和 21 的含义
  3. php ascii hex编码
  4. 向腾讯云windows服务器传输文件,如何上传本地文件到腾讯云Windows服务器上?
  5. java达达租车接口_Java第一个项目——达达租车系统v1
  6. Python安装Jupyter Notebook配置使用教程
  7. mysql安装mac 压缩包_MAC mysql安装及设置
  8. In App Purchases 入门
  9. tf.concat, np.concatenate
  10. 交易系统开发(四)——交易柜台系统
  11. clousx6机器人怎么导入词库_clousx6词库编程从零入门:变量总结
  12. 图像处理之matlab中imnoise函数用法详解
  13. pb语言是什么计算机语言,pb编程语言
  14. 铣削力matlab,船用螺旋桨多轴铣削力仿真与优化+CAD图纸+MATLAB程序
  15. HashMap排序(java)
  16. 多元时间序列预测 —— 向量自回归(VAR)
  17. HMC510LP5ETR资料
  18. 实验五 类和对象-3 zxt
  19. css 控制 段落 超出三行的部分显示...
  20. 【渝粤教育】广东开放大学 古代汉语 形成性考核 (28)

热门文章

  1. SAP ERP是什么意思?
  2. 最长回文子串Java
  3. 武汉理工大学 大数据架构与模式期末复习
  4. 【支付系统学习笔记】-二支付设计(银行卡支付)
  5. IE 10 禁用多点触摸放大缩小页面
  6. C语言入门——递归(思想简要讲解+简单递归练习)
  7. 如何完全卸载VS2010(亲自体验过)
  8. Tomcat 7 相关参数优化说明及配置最佳案例
  9. Tomcat7之性能优化
  10. 二叉树结构与算法思路解析