📄 iwlist.c
字号:
printf(" Mode:%s\n", iw_operation_mode[event->u.mode]); break; case SIOCGIWNAME: printf(" Protocol:%-1.16s\n", event->u.name); break; case SIOCGIWESSID: { char essid[IW_ESSID_MAX_SIZE+1]; memset(essid, '\0', sizeof(essid)); if((event->u.essid.pointer) && (event->u.essid.length)) memcpy(essid, event->u.essid.pointer, event->u.essid.length); if(event->u.essid.flags) { /* Does it have an ESSID index ? */ if((event->u.essid.flags & IW_ENCODE_INDEX) > 1) printf(" ESSID:\"%s\" [%d]\n", essid, (event->u.essid.flags & IW_ENCODE_INDEX)); else printf(" ESSID:\"%s\"\n", essid); } else printf(" ESSID:off/any/hidden\n"); } break; case SIOCGIWENCODE: { unsigned char key[IW_ENCODING_TOKEN_MAX]; if(event->u.data.pointer) memcpy(key, event->u.data.pointer, event->u.data.length); else event->u.data.flags |= IW_ENCODE_NOKEY; printf(" Encryption key:"); if(event->u.data.flags & IW_ENCODE_DISABLED) printf("off\n"); else { /* Display the key */ iw_print_key(buffer, sizeof(buffer), key, event->u.data.length, event->u.data.flags); printf("%s", buffer); /* Other info... */ if((event->u.data.flags & IW_ENCODE_INDEX) > 1) printf(" [%d]", event->u.data.flags & IW_ENCODE_INDEX); if(event->u.data.flags & IW_ENCODE_RESTRICTED) printf(" Security mode:restricted"); if(event->u.data.flags & IW_ENCODE_OPEN) printf(" Security mode:open"); printf("\n"); } } break; case SIOCGIWRATE: if(state->val_index == 0) printf(" Bit Rates:"); else if((state->val_index % 5) == 0) printf("\n "); else printf("; "); iw_print_bitrate(buffer, sizeof(buffer), event->u.bitrate.value); printf("%s", buffer); /* Check for termination */ if(stream->value == NULL) { printf("\n"); state->val_index = 0; } else state->val_index++; break; case IWEVQUAL: { iw_print_stats(buffer, sizeof(buffer), &event->u.qual, iw_range, has_range); printf(" %s\n", buffer); break; } case IWEVGENIE: /* Informations Elements are complex, let's do only some of them */ iw_print_gen_ie(event->u.data.pointer, event->u.data.length); break; case IWEVCUSTOM: { char custom[IW_CUSTOM_MAX+1]; if((event->u.data.pointer) && (event->u.data.length)) memcpy(custom, event->u.data.pointer, event->u.data.length); custom[event->u.data.length] = '\0'; printf(" Extra:%s\n", custom); } break; default: printf(" (Unknown Wireless Token 0x%04X)\n", event->cmd); } /* switch(event->cmd) */}/*------------------------------------------------------------------*//* * Perform a scanning on one device */static intprint_scanning_info(int skfd, char * ifname, char * args[], /* Command line args */ int count) /* Args count */{ struct iwreq wrq; unsigned char * buffer = NULL; /* Results */ int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */ struct iw_range range; int has_range; struct timeval tv; /* Select timeout */ int timeout = 15000000; /* 15s */ /* Avoid "Unused parameter" warning */ args = args; count = count; /* Get range stuff */ has_range = (iw_get_range_info(skfd, ifname, &range) >= 0); /* Check if the interface could support scanning. */ if((!has_range) || (range.we_version_compiled < 14)) { fprintf(stderr, "%-8.16s Interface doesn't support scanning.\n\n", ifname); return(-1); } /* Init timeout value -> 250ms*/ tv.tv_sec = 0; tv.tv_usec = 250000; /* * Here we should look at the command line args and set the IW_SCAN_ flags * properly */ wrq.u.data.pointer = NULL; /* Later */ wrq.u.data.flags = 0; wrq.u.data.length = 0; /* Initiate Scanning */ if(iw_set_ext(skfd, ifname, SIOCSIWSCAN, &wrq) < 0) { if(errno != EPERM) { fprintf(stderr, "%-8.16s Interface doesn't support scanning : %s\n\n", ifname, strerror(errno)); return(-1); } /* If we don't have the permission to initiate the scan, we may * still have permission to read left-over results. * But, don't wait !!! */#if 0 /* Not cool, it display for non wireless interfaces... */ fprintf(stderr, "%-8.16s (Could not trigger scanning, just reading left-over results)\n", ifname);#endif tv.tv_usec = 0; } timeout -= tv.tv_usec; /* Forever */ while(1) { fd_set rfds; /* File descriptors for select */ int last_fd; /* Last fd */ int ret; /* Guess what ? We must re-generate rfds each time */ FD_ZERO(&rfds); last_fd = -1; /* In here, add the rtnetlink fd in the list */ /* Wait until something happens */ ret = select(last_fd + 1, &rfds, NULL, NULL, &tv); /* Check if there was an error */ if(ret < 0) { if(errno == EAGAIN || errno == EINTR) continue; fprintf(stderr, "Unhandled signal - exiting...\n"); return(-1); } /* Check if there was a timeout */ if(ret == 0) { unsigned char * newbuf; realloc: /* (Re)allocate the buffer - realloc(NULL, len) == malloc(len) */ newbuf = realloc(buffer, buflen); if(newbuf == NULL) { if(buffer) free(buffer); fprintf(stderr, "%s: Allocation failed\n", __FUNCTION__); return(-1); } buffer = newbuf; /* Try to read the results */ wrq.u.data.pointer = buffer; wrq.u.data.flags = 0; wrq.u.data.length = buflen; if(iw_get_ext(skfd, ifname, SIOCGIWSCAN, &wrq) < 0) { /* Check if buffer was too small (WE-17 only) */ if((errno == E2BIG) && (range.we_version_compiled > 16)) { /* Some driver may return very large scan results, either * because there are many cells, or because they have many * large elements in cells (like IWEVCUSTOM). Most will * only need the regular sized buffer. We now use a dynamic * allocation of the buffer to satisfy everybody. Of course, * as we don't know in advance the size of the array, we try * various increasing sizes. Jean II */ /* Check if the driver gave us any hints. */ if(wrq.u.data.length > buflen) buflen = wrq.u.data.length; else buflen *= 2; /* Try again */ goto realloc; } /* Check if results not available yet */ if(errno == EAGAIN) { /* Restart timer for only 100ms*/ tv.tv_sec = 0; tv.tv_usec = 100000; timeout -= tv.tv_usec; if(timeout > 0) continue; /* Try again later */ } /* Bad error */ free(buffer); fprintf(stderr, "%-8.16s Failed to read scan data : %s\n\n", ifname, strerror(errno)); return(-2); } else /* We have the results, go to process them */ break; } /* In here, check if event and event type * if scan event, read results. All errors bad & no reset timeout */ } if(wrq.u.data.length) { struct iw_event iwe; struct stream_descr stream; struct iwscan_state state = { .ap_num = 1, .val_index = 0 }; int ret; #if 0 /* Debugging code. In theory useless, because it's debugged ;-) */ int i; printf("Scan result %d [%02X", wrq.u.data.length, buffer[0]); for(i = 1; i < wrq.u.data.length; i++) printf(":%02X", buffer[i]); printf("]\n");#endif printf("%-8.16s Scan completed :\n", ifname); iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length); do { /* Extract an event and print it */ ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled); if(ret > 0) print_scanning_token(&stream, &iwe, &state, &range, has_range); } while(ret > 0); printf("\n"); } else printf("%-8.16s No scan results\n", ifname); free(buffer); return(0);}/******************** WIRELESS EVENT CAPABILITY ********************/static const char * event_capa_req[] ={ [SIOCSIWNWID - SIOCIWFIRST] = "Set NWID (kernel generated)", [SIOCSIWFREQ - SIOCIWFIRST] = "Set Frequency/Channel (kernel generated)", [SIOCGIWFREQ - SIOCIWFIRST] = "New Frequency/Channel", [SIOCSIWMODE - SIOCIWFIRST] = "Set Mode (kernel generated)", [SIOCGIWTHRSPY - SIOCIWFIRST] = "Spy threshold crossed", [SIOCGIWAP - SIOCIWFIRST] = "New Access Point/Cell address - roaming", [SIOCGIWSCAN - SIOCIWFIRST] = "Scan request completed", [SIOCSIWESSID - SIOCIWFIRST] = "Set ESSID (kernel generated)", [SIOCGIWESSID - SIOCIWFIRST] = "New ESSID", [SIOCGIWRATE - SIOCIWFIRST] = "New bit-rate", [SIOCSIWENCODE - SIOCIWFIRST] = "Set Encoding (kernel generated)", [SIOCGIWPOWER - SIOCIWFIRST] = NULL,};static const char * event_capa_evt[] ={ [IWEVTXDROP - IWEVFIRST] = "Tx packet dropped - retry exceeded", [IWEVCUSTOM - IWEVFIRST] = "Custom driver event", [IWEVREGISTERED - IWEVFIRST] = "Registered node", [IWEVEXPIRED - IWEVFIRST] = "Expired node",};/*------------------------------------------------------------------*//* * Print the number of available transmit powers for the device */static intprint_event_capa_info(int skfd, char * ifname, char * args[], /* Command line args */ int count) /* Args count */{ struct iw_range range; int cmd; /* Avoid "Unused parameter" warning */ args = args; count = count; /* Extract range info */ if((iw_get_range_info(skfd, ifname, &range) < 0) || (range.we_version_compiled < 10)) fprintf(stderr, "%-8.16s no wireless event capability information.\n\n", ifname); else {#if 0 /* Debugging ;-) */ for(cmd = 0x8B00; cmd < 0x8C0F; cmd++) { int idx = IW_EVENT_CAPA_INDEX(cmd); int mask = IW_EVENT_CAPA_MASK(cmd); printf("0x%X - %d - %X\n", cmd, idx, mask); }#endif printf("%-8.16s Wireless Events supported :\n", ifname); for(cmd = SIOCIWFIRST; cmd <= SIOCGIWPOWER; cmd++) { int idx = IW_EVENT_CAPA_INDEX(cmd); int mask = IW_EVENT_CAPA_MASK(cmd); if(range.event_capa[idx] & mask) printf(" 0x%04X : %s\n", cmd, event_capa_req[cmd - SIOCIWFIRST]); } for(cmd = IWEVFIRST; cmd <= IWEVEXPIRED; cmd++) { int idx = IW_EVENT_CAPA_INDEX(cmd); int mask = IW_EVENT_CAPA_MASK(cmd); if(range.event_capa[idx] & mask) printf(" 0x%04X : %s\n", cmd, event_capa_evt[cmd - IWEVFIRST]); } printf("\n"); } return(0);}/************************* COMMON UTILITIES *************************//* * This section was initially written by Michael Tokarev <mjt@tls.msk.ru> * but heavily modified by me ;-) *//*------------------------------------------------------------------*//* * Map command line arguments to the proper procedure... */typedef struct iwlist_entry { const char *cmd; iw_enum_handler fn; int min_count; int max_count;} iwlist_cmd;static const struct iwlist_entry iwlist_cmds[] = { { "scanning", print_scanning_info, 0, 5 }, { "frequency", print_freq_info, 0, 0 }, { "channel", print_freq_info, 0, 0 }, { "bitrate", print_bitrate_info, 0, 0 }, { "rate", print_bitrate_info, 0, 0 }, { "encryption", print_keys_info, 0, 0 }, { "key", print_keys_info, 0, 0 }, { "power", print_pm_info, 0, 0 }, { "txpower", print_txpower_info, 0, 0 }, { "retry", print_retry_info, 0, 0 }, { "ap", print_ap_info, 0, 0 }, { "accesspoints", print_ap_info, 0, 0 }, { "peers", print_ap_info, 0, 0 }, { "event", print_event_capa_info, 0, 0 }, { NULL, NULL, 0, 0 },};/*------------------------------------------------------------------*//* * Find the most appropriate command matching the command line */static inline const iwlist_cmd *find_command(const char * cmd){ const iwlist_cmd * found = NULL; int ambig = 0; unsigned int len = strlen(cmd); int i; /* Go through all commands */ for(i = 0; iwlist_cmds[i].cmd != NULL; ++i) { /* No match -> next one */ if(strncasecmp(iwlist_cmds[i].cmd, cmd, len) != 0) continue; /* Exact match -> perfect */ if(len == strlen(iwlist_cmds[i].cmd)) return &iwlist_cmds[i]; /* Partial match */ if(found == NULL) /* First time */ found = &iwlist_cmds[i]; else /* Another time */ if (iwlist_cmds[i].fn != found->fn) ambig = 1; } if(found == NULL) { fprintf(stderr, "iwlist: unknown command `%s'\n", cmd); return NULL; } if(ambig) { fprintf(stderr, "iwlist: command `%s' is ambiguous\n", cmd); return NULL; } return found;}/*------------------------------------------------------------------*//* * Display help */static void iw_usage(int status){ FILE* f = status ? stderr : stdout; int i; fprintf(f, "Usage: iwlist [interface] %s\n", iwlist_cmds[0].cmd); for(i = 1; iwlist_cmds[i].cmd != NULL; ++i) fprintf(f, " [interface] %s\n", iwlist_cmds[i].cmd); exit(status);}/******************************* MAIN ********************************//*------------------------------------------------------------------*//* * The main ! */intmain(int argc, char ** argv){ int skfd; /* generic raw socket desc. */ char *dev; /* device name */ char *cmd; /* command */ char **args; /* Command arguments */ int count; /* Number of arguments */ const iwlist_cmd *iwcmd; if(argc == 1 || argc > 3) iw_usage(1); /* Those don't apply to all interfaces */ if((argc == 2) && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) iw_usage(0); if((argc == 2) && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))) return(iw_print_version_info("iwlist")); if(argc == 2) { cmd = argv[1]; dev = NULL; args = NULL; count = 0; } else { cmd = argv[2]; dev = argv[1]; args = argv + 3; count = argc - 3; } /* find a command */ iwcmd = find_command(cmd); if(iwcmd == NULL) return 1; /* Check arg numbers */ if(count < iwcmd->min_count) { fprintf(stderr, "iwlist: command `%s' needs more arguments\n", cmd); return 1; } if(count > iwcmd->max_count) { fprintf(stderr, "iwlist: command `%s' needs fewer arguments\n", cmd); return 1; } /* Create a channel to the NET kernel. */ if((skfd = iw_sockets_open()) < 0) { perror("socket"); return -1; } /* do the actual work */ if (dev) (*iwcmd->fn)(skfd, dev, args, count); else iw_enum_devices(skfd, iwcmd->fn, args, count); /* Close the socket. */ iw_sockets_close(skfd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -