wireless-tools源码分析-iwpriv
2017-02-24 12:19
337 查看
iwpriv是Wireless Extensions 操作的特定驱动。通过iwpriv,可以得到AP的一些参数设置,也可以设置自己的WIFI参数。
iwpriv源码中的main函数,内容如下:
使用了
私有数据使用
可以看到使用了
iwpriv的设置通过
[root@root- /]#iwpriv wlan0 Available private ioctls : extscan (8BFA) : set 0 int & get 2 char hostcmd (8BE4) : set 2047 byte & get 2047 byte arpfilter (8BE6) : set 2047 byte & get 2047 byte regrdwr (8BE3) : set 256 char & get 256 char sdcmd52rw (8BFE) : set 7 byte & get 7 byte sdcmd53rw (8BFF) : set 0 char & get 0 char setgetconf (8BEA) : set 2000 byte & get 2000 byte getcis (8BE1) : set 0 & get 512 byte scantype (8BEB) : set 8 char & get 8 char deauth (0001) : set 1 addr & get 0 getNF (0001) : set 1 int & get 1 int getRSSI (0002) : set 1 int & get 1 int bgscan (0004) : set 1 int & get 1 int enable11d (0005) : set 1 int & get 1 int adhocgrate (0006) : set 1 int & get 1 int sdioclock (0007) : set 1 int & get 1 int wmm (0008) : set 1 int & get 1 int uapsdnullgen (000A) : set 1 int & get 1 int setcoalescing (000B) : set 1 int & get 1 int adhocgprot (000C) : set 1 int & get 1 int disable_chsw (000F) : set 1 int & get 1 int setpowercons (0001) : set 1 int & get 1 int wmm_qosinfo (0002) : set 1 int & get 1 int lolisteninter (0003) : set 1 int & get 1 int psnullinterval (0005) : set 1 int & get 1 int bcnmisto (0006) : set 1 int & get 1 int ldocfg (0008) : set 1 int & get 1 int rtsctsctrl (000F) : set 1 int & get 1 int moduletype (000B) : set 1 int & get 1 int autodeepsleep (000C) : set 1 int & get 1 int enhanceps (000D) : set 1 int & get 1 int wakeupmt (000E) : set 1 int & get 1 int setrxant (0001) : set 1 int & get 0 settxant (0002) : set 1 int & get 0 authalgs (0004) : set 1 int & get 0 encryptionmode (0005) : set 1 int & get 0 setregioncode (0006) : set 1 int & get 0 setlisteninter (0007) : set 1 int & get 0 setmultipledtim (0008) : set 1 int & get 0 setbcnavg (0009) : set 1 int & get 0 setdataavg (000A) : set 1 int & get 0 associate (000B) : set 1 int & get 0 getregioncode (0001) : set 0 & get 1 int getlisteninter (0002) : set 0 & get 1 int getmultipledtim (0003) : set 0 & get 1 int gettxrate (0004) : set 0 & get 1 int getbcnavg (0005) : set 0 & get 1 int getdataavg (0006) : set 0 & get 1 int getauthtype (0007) : set 0 & get 1 int getrsnmode (0008) : set 0 & get 1 int act_paircipher (0009) : set 0 & get 1 int act_groupcipher (000A) : set 0 & get 1 int getdtim (000B) : set 0 & get 1 int getrxant (0001) : set 0 & get 12 char gettxant (0002) : set 0 & get 12 char gettsf (0003) : set 0 & get 12 char wpssession (0004) : set 0 & get 12 char deepsleep (8BFB) : set 1 char & get 6 char adhocstop (0004) : set 0 & get 0 radioon (0001) : set 0 & get 0 radiooff (0002) : set 0 & get 0 rmaeskey (0003) : set 0 & get 0 crypto_test (0006) : set 0 & get 0 reasso-on (0007) : set 0 & get 0 reasso-off (0008) : set 0 & get 0 wlanidle-on (0009) : set 0 & get 0 wlanidle-off (000A) : set 0 & get 0 softreset (000C) : set 0 & get 0 sleepparams (0002) : set 64 char & get 64 char requesttpc (0004) : set 64 char & get 64 char powercap (0005) : set 64 char & get 64 char measreq (000C) : set 64 char & get 64 char bca-ts (0003) : set 64 char & get 64 char scanmode (0006) : set 64 char & get 64 char getadhocstatus (0009) : set 64 char & get 64 char setgenie (000A) : set 64 char & get 64 char getgenie (000B) : set 64 char & get 64 char qstatus (000D) : set 64 char & get 64 char ts_status (000E) : set 64 char & get 64 char setaeskey (0001) : set 32 char & get 0 getaeskey (0001) : set 1 int & get 128 char version (0002) : set 1 int & get 128 char verext (0003) : set 1 int & get 128 char setwpaie (8BE0) : set 24 char & get 0 setband (0001) : set 10 char & get 0 setadhocch (0002) : set 10 char & get 0 chanswann (0003) : set 10 char & get 0 getband (0001) : set 0 & get 10 char getadhocch (0002) : set 0 & get 10 char getlog (8BE9) : set 0 & get 512 char tpccfg (0001) : set 16 int & get 16 int scanprobes (0006) : set 16 int & get 16 int ledgpio (0005) : set 16 int & get 16 int sleeppd (0007) : set 16 int & get 16 int rateadapt (0008) : set 16 int & get 16 int getSNR (0009) : set 16 int & get 16 int getrate (000A) : set 16 int & get 16 int getrxinfo (000B) : set 16 int & get 16 int atimwindow (000C) : set 16 int & get 16 int bcninterval (000D) : set 16 int & get 16 int sdiopullctrl (000E) : set 16 int & get 16 int scantime (000F) : set 16 int & get 16 int sysclock (0010) : set 16 int & get 16 int txcontrol (0012) : set 16 int & get 16 int hscfg (0014) : set 16 int & get 16 int hssetpara (0015) : set 16 int & get 16 int inactoext (0016) : set 16 int & get 16 int dbgscfg (0017) : set 16 int & get 16 int drvdbg (0018) : set 16 int & get 16 int drvdelaymax (001A) : set 16 int & get 16 int intfctrl (001B) : set 16 int & get 16 int setquietie (001C) : set 16 int & get 16 int ctspowerctrl (001E) : set 16 int & get 16 int psmode (001F) : set 16 int & get 16 int setuserscan (0001) : set 2000 byte & get 2000 byte getscantable (0002) : set 2000 byte & get 2000 byte setmrvltlv (0003) : set 2000 byte & get 2000 byte getassocrsp (0004) : set 2000 byte & get 2000 byte addts (0005) : set 2000 byte & get 2000 byte delts (0006) : set 2000 byte & get 2000 byte qconfig (0007) : set 2000 byte & get 2000 byte qstats (0008) : set 2000 byte & get 2000 byte txpktstats (000C) : set 2000 byte & get 2000 byte getcfptable (0009) : set 2000 byte & get 2000 byte mefcfg (000A) : set 2000 byte & get 2000 byte getmem (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; else maxpriv *= 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 0 printf("<mapping sub-ioctl %s to cmd 0x%X-%d>\n", cmdname, priv[k].cmd, subcmd); #endif } /* If we have to set some data */ if((priv[k].set_args & IW_PRIV_TYPE_MASK) && (priv[k].set_args & IW_PRIV_SIZE_MASK)) { switch(priv[k].set_args & IW_PRIV_TYPE_MASK) { case IW_PRIV_TYPE_BYTE: /* Number of args to fetch */ wrq.u.data.length = count; if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK)) wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK; /* Fetch args */ for(; i < wrq.u.data.length; i++) { sscanf(args[i], "%i", &temp); buffer[i] = (char) temp; } break; case IW_PRIV_TYPE_INT: /* Number of args to fetch */ wrq.u.data.length = count; if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK)) wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK; /* Fetch args */ for(; i < wrq.u.data.length; i++) { sscanf(args[i], "%i", &temp); ((__s32 *) buffer)[i] = (__s32) temp; } break; case IW_PRIV_TYPE_CHAR: if(i < count) { /* Size of the string to fetch */ wrq.u.data.length = strlen(args[i]) + 1; if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK)) wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK; /* Fetch string */ memcpy(buffer, args[i], wrq.u.data.length); buffer[sizeof(buffer) - 1] = '\0'; i++; } else { wrq.u.data.length = 1; buffer[0] = '\0'; } break; case IW_PRIV_TYPE_FLOAT: /* Number of args to fetch */ wrq.u.data.length = count; if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK)) wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK; /* Fetch args */ for(; i < wrq.u.data.length; i++) { double freq; if(sscanf(args[i], "%lg", &(freq)) != 1) { printf("Invalid float [%s]...\n", args[i]); return(-1); } if(strchr(args[i], 'G')) freq *= GIGA; if(strchr(args[i], 'M')) freq *= MEGA; if(strchr(args[i], 'k')) freq *= KILO; sscanf(args[i], "%i", &temp); iw_float2freq(freq, ((struct iw_freq *) buffer) + i); } break; case IW_PRIV_TYPE_ADDR: /* Number of args to fetch */ wrq.u.data.length = count; if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK)) wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK; /* Fetch args */ for(; i < wrq.u.data.length; i++) { if(iw_in_addr(skfd, ifname, args[i], ((struct sockaddr *) buffer) + i) < 0) { printf("Invalid address [%s]...\n", args[i]); return(-1); } } break; default: fprintf(stderr, "Not implemented...\n"); return(-1); } if((priv[k].set_args & IW_PRIV_SIZE_FIXED) && (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK))) { printf("The command %s needs exactly %d argument(s)...\n", cmdname, priv[k].set_args & IW_PRIV_SIZE_MASK); return(-1); } } /* if args to set */ else { wrq.u.data.length = 0L; } strncpy(wrq.ifr_name, ifname, IFNAMSIZ); /* Those two tests are important. They define how the driver * will have to handle the data */ if((priv[k].set_args & IW_PRIV_SIZE_FIXED) && ((iw_get_priv_size(priv[k].set_args) + offset) <= IFNAMSIZ)) { /* First case : all SET args fit within wrq */ if(offset) wrq.u.mode = subcmd; memcpy(wrq.u.name + offset, buffer, IFNAMSIZ - offset); } else { if((priv[k].set_args == 0) && (priv[k].get_args & IW_PRIV_SIZE_FIXED) && (iw_get_priv_size(priv[k].get_args) <= IFNAMSIZ)) { /* Second case : no SET args, GET args fit within wrq */ if(offset) wrq.u.mode = subcmd; } else { /* Third case : args won't fit in wrq, or variable number of args */ wrq.u.data.pointer = (caddr_t) buffer; wrq.u.data.flags = subcmd; } } /* Perform the private ioctl */ if(ioctl(skfd, priv[k].cmd, &wrq) < 0) { fprintf(stderr, "Interface doesn't accept private ioctl...\n"); fprintf(stderr, "%s (%X): %s\n", cmdname, priv[k].cmd, strerror(errno)); return(-1); } /* If we have to get some data */ if((priv[k].get_args & IW_PRIV_TYPE_MASK) && (priv[k].get_args & IW_PRIV_SIZE_MASK)) { int j; int n = 0; /* number of args */ printf("%-8.16s %s:", ifname, cmdname); /* Check where is the returned data */ if((priv[k].get_args & IW_PRIV_SIZE_FIXED) && (iw_get_priv_size(priv[k].get_args) <= IFNAMSIZ)) { memcpy(buffer, wrq.u.name, IFNAMSIZ); n = priv[k].get_args & IW_PRIV_SIZE_MASK; } else n = wrq.u.data.length; switch(priv[k].get_args & IW_PRIV_TYPE_MASK) { case IW_PRIV_TYPE_BYTE: /* Display args */ for(j = 0; j < n; j++) printf("%d ", buffer[j]); printf("\n"); break; case IW_PRIV_TYPE_INT: /* Display args */ for(j = 0; j < n; j++) printf("%d ", ((__s32 *) buffer)[j]); printf("\n"); break; case IW_PRIV_TYPE_CHAR: /* Display args */ buffer = '\0'; printf("%s\n", buffer); break; case IW_PRIV_TYPE_FLOAT: { double freq; /* Display args */ for(j = 0; j < n; j++) { freq = iw_freq2float(((struct iw_freq *) buffer) + j); if(freq >= GIGA) printf("%gG ", freq / GIGA); else if(freq >= MEGA) printf("%gM ", freq / MEGA); else printf("%gk ", freq / KILO); } printf("\n"); } break; case IW_PRIV_TYPE_ADDR: { char scratch[128]; struct sockaddr * hwa; /* Display args */ for(j = 0; j < n; j++) { hwa = ((struct sockaddr *) buffer) + j; if(j) printf(" %.*s", (int) strlen(cmdname), " "); printf("%s\n", iw_saether_ntop(hwa, scratch)); } } break; default: fprintf(stderr, "Not yet implemented...\n"); return(-1); } } /* if args to set */ return(0); }
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源码分析-iwconfig
- wireless-tools源码分析-iwlist
- KVM虚拟化源码分析之KVM_TOOLS(一)
- KVM虚拟化源码分析之KVM_TOOLS(三)
- KVM虚拟化源码分析之KVM_TOOLS(四)
- KVM虚拟化源码分析之KVM_TOOLS(二)
- pybitcointools源码分析之RFC6979
- ros源码分析(6)—roslaunch Commandline Tools
- pybitcointools源码分析之BIP32实现
- KVM虚拟化源码分析之KVM_TOOLS(五)
- SharpDevelop源码分析 (三、插件系统)
- JBPM源码分析(一)---数据库表主键ID的产生机制
- Struts-menu源码分析(转贴)
- PC键盘驱动程序源码分析
- TOMCAT源码分析(启动框架)
- BO2k源码分析(二)----命令循环机制
- 源码分析:HashMap
- String转换成Integer源码分析
- VCL源码分析方法论 cg1120(原作)
- JBPM源码分析(二)---acceptToken函数