wireless-tools源码分析-iwpriv
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相关推荐
- Spring Developer Tools 源码分析:二、类路径监控
在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...
- kazoo源码分析:Zookeeper客户端start概述
kazoo源码分析 kazoo-2.6.1 kazoo客户端 kazoo是一个由Python编写的zookeeper客户端,实现了zookeeper协议,从而提供了Python与zookeeper服务 ...
- kubeadm源码分析(内含kubernetes离线包,三步安装)
k8s离线安装包 三步安装,简单到难以置信 kubeadm源码分析 说句实在话,kubeadm的代码写的真心一般,质量不是很高. 几个关键点来先说一下kubeadm干的几个核心的事: kubeadm ...
- 《深入理解Spark:核心思想与源码分析》——1.2节Spark初体验
本节书摘来自华章社区<深入理解Spark:核心思想与源码分析>一书中的第1章,第1.2节Spark初体验,作者耿嘉安,更多章节内容可以访问云栖社区"华章社区"公众号查看 ...
- soundtouch源码分析__based on csdn :
1. soundtouch介绍和相关资源 The SoundTouch Library Copyright © Olli Parviainen 2001-2014 SoundTouch is an o ...
- linux nDPI 协议检测 源码分析
关于nDPI的基本功能就不在这介绍了,有兴趣了解的读者可以阅读官方的快速入门指南:https://github.com/ntop/nDPI/blob/dev/doc/nDPI_QuickStartGu ...
- java 源码分析_Java 源代码编译成 Class 文件的过程分析
原标题:Java 源代码编译成 Class 文件的过程分析 在上篇文章< Java三种编译方式:前端编译 JIT编译 AOT编译 >中了解到了它们各有什么优点和缺点,以及前端编译+JIT编 ...
- 【Android 插件化】VirtualApp 源码分析 ( 添加应用源码分析 | LaunchpadAdapter 适配器 | 适配器添加元素 | PackageAppData 元素 )
文章目录 一.添加应用源码分析 1.LaunchpadAdapter 适配器 2.适配器添加元素 3.PackageAppData 元素 一.添加应用源码分析 1.LaunchpadAdapter 适 ...
- zg手册 之 python2.7.7源码分析(1)-- python中的对象
为什么80%的码农都做不了架构师?>>> 源代码主要目录结构 Demo: python 的示例程序 Doc: 文档 Grammar: 用BNF的语法定义了Python的全部语法 ...
最新文章
- 洛谷 - P1426 - 小鱼会有危险吗 - 模拟
- linux命令后面常见的/dev/null 和 21 的含义
- php ascii hex编码
- 向腾讯云windows服务器传输文件,如何上传本地文件到腾讯云Windows服务器上?
- java达达租车接口_Java第一个项目——达达租车系统v1
- Python安装Jupyter Notebook配置使用教程
- mysql安装mac 压缩包_MAC mysql安装及设置
- In App Purchases 入门
- tf.concat, np.concatenate
- 交易系统开发(四)——交易柜台系统
- clousx6机器人怎么导入词库_clousx6词库编程从零入门:变量总结
- 图像处理之matlab中imnoise函数用法详解
- pb语言是什么计算机语言,pb编程语言
- 铣削力matlab,船用螺旋桨多轴铣削力仿真与优化+CAD图纸+MATLAB程序
- HashMap排序(java)
- 多元时间序列预测 —— 向量自回归(VAR)
- HMC510LP5ETR资料
- 实验五 类和对象-3 zxt
- css 控制 段落 超出三行的部分显示...
- 【渝粤教育】广东开放大学 古代汉语 形成性考核 (28)