- 下載: wireless tools for linux Wireless Tools (WT)
- 編譯: make make install (default: /usr/local/sbin)
- 指令:
iwconfig
iwlist
iwspy
iwpriv
ifrename
- 使用:
iwlist wlan0 scanning | grep -e ESSID -e Quality -e Encryption -e IE
有時候不知為什麼會出現不少沒名字的
ex: ESSID:""
iwlist wlan0 scan | grep -E 'ESSID:".+"' or iwlist wlan0 scan | grep 'ESSID:"..*"'ref: Here
為了方便分析,把原本iwlist的印出方法改了一下
- iwlib.c, (copy it from wireless tools for linux)
... ... ... void iw_print_stats(char * buffer, int buflen, const iwqual * qual, const iwrange * range, int has_range) { int len; ... ... ... if(has_range && ((qual->level != 0) || (qual->updated & (IW_QUAL_DBM | IW_QUAL_RCPI)))) { /* Deal with quality : always a relative value */ if(!(qual->updated & IW_QUAL_QUAL_INVALID)) { len = snprintf(buffer, buflen, "Quality%c%d/%d ", qual->updated & IW_QUAL_QUAL_UPDATED ? '=' : ':', qual->qual, range->max_qual.qual); buffer += len; buflen -= len; } /* Check if the statistics are in RCPI (IEEE 802.11k) */ if(qual->updated & IW_QUAL_RCPI) { /* Deal with signal level in RCPI */ /* RCPI = int{(Power in dBm +110)*2} for 0dbm > Power > -110dBm */ if(!(qual->updated & IW_QUAL_LEVEL_INVALID)) { double rcpilevel = (qual->level / 2.0) - 110.0; len = snprintf(buffer, buflen, "Signal level%c%g dBm ", qual->updated & IW_QUAL_LEVEL_UPDATED ? '=' : ':', rcpilevel); buffer += len; buflen -= len; } /* Deal with noise level in dBm (absolute power measurement) */ if(!(qual->updated & IW_QUAL_NOISE_INVALID)) { double rcpinoise = (qual->noise / 2.0) - 110.0; len = snprintf(buffer, buflen, "Noise level%c%g dBm", qual->updated & IW_QUAL_NOISE_UPDATED ? '=' : ':', rcpinoise); } } else { /* Check if the statistics are in dBm */ if((qual->updated & IW_QUAL_DBM) || (qual->level > range->max_qual.level)) { /* Deal with signal level in dBm (absolute power measurement) */ if(!(qual->updated & IW_QUAL_LEVEL_INVALID)) { int dblevel = qual->level; /* Implement a range for dBm [-192; 63] */ if(qual->level >= 64) dblevel -= 0x100; len = snprintf(buffer, buflen, "Signal level%c%d dBm ", qual->updated & IW_QUAL_LEVEL_UPDATED ? '=' : ':', dblevel); buffer += len; buflen -= len; } /* Deal with noise level in dBm (absolute power measurement) */ if(!(qual->updated & IW_QUAL_NOISE_INVALID)) { int dbnoise = qual->noise; /* Implement a range for dBm [-192; 63] */ if(qual->noise >= 64) dbnoise -= 0x100; len = snprintf(buffer, buflen, "Noise level%c%d dBm", qual->updated & IW_QUAL_NOISE_UPDATED ? '=' : ':', dbnoise); } } else { /* Deal with signal level as relative value (0 -> max) */ if(!(qual->updated & IW_QUAL_LEVEL_INVALID)) { len = snprintf(buffer, buflen, "Signal level%c%d/%d ", qual->updated & IW_QUAL_LEVEL_UPDATED ? '=' : ':', qual->level, range->max_qual.level); buffer += len; buflen -= len; } /* Deal with noise level as relative value (0 -> max) */ if(!(qual->updated & IW_QUAL_NOISE_INVALID)) { len = snprintf(buffer, buflen, "Noise level%c%d/%d", qual->updated & IW_QUAL_NOISE_UPDATED ? '=' : ':', qual->noise, range->max_qual.noise); } } } } else { /* We can't read the range, so we don't know... */ snprintf(buffer, buflen, "Quality:%d Signal level:%d Noise level:%d", qual->qual, qual->level, qual->noise); } } ... ... ...
- iwlist.c (iwlist_aaa.c), copy it from wireless tools for linux
... ... ... int FLAG=0; //golbal value ... ... ... /*------------------------------------------------------------------*/ /* * Parse, and display the results of a WPA or WPA2 IE. * */ static inline void iw_print_ie_wpa(unsigned char * iebuf, int buflen) { int ielen = iebuf[1] + 2; int offset = 2; /* Skip the IE id, and the length. */ unsigned char wpa1_oui[3] = {0x00, 0x50, 0xf2}; unsigned char wpa2_oui[3] = {0x00, 0x0f, 0xac}; unsigned char * wpa_oui; int i; uint16_t ver = 0; uint16_t cnt = 0; if(ielen > buflen) ielen = buflen; #ifdef DEBUG /* Debugging code. In theory useless, because it's debugged ;-) */ printf("IE raw value %d [%02X", buflen, iebuf[0]); for(i = 1; i < buflen; i++) printf(":%02X", iebuf[i]); printf("]\n"); #endif switch(iebuf[0]) { case 0x30: /* WPA2 */ /* Check if we have enough data */ if(ielen < 4) { //iw_print_ie_unknown(iebuf, buflen); //LN2 co return; } wpa_oui = wpa2_oui; break; case 0xdd: /* WPA or else */ wpa_oui = wpa1_oui; /* Not all IEs that start with 0xdd are WPA. * So check that the OUI is valid. Note : offset==2 */ if((ielen < 8) || (memcmp(&iebuf[offset], wpa_oui, 3) != 0) || (iebuf[offset + 3] != 0x01)) { //iw_print_ie_unknown(iebuf, buflen); //LN2 co return; } /* Skip the OUI type */ offset += 4; break; default: return; } /* Pick version number (little endian) */ ver = iebuf[offset] | (iebuf[offset + 1] << 8); offset += 2; if(iebuf[0] == 0xdd) { printf(" IE: "); //LN2 //printf("WPA Version %d\n", ver); //LN2 co printf("WPAver%d\n", ver); } if(iebuf[0] == 0x30) { printf(" IE: "); //LN2 //printf("IEEE 802.11i/WPA2 Version %d\n", ver); //LN2 co printf("WPA2ver%d\n", ver); } /* From here, everything is technically optional. */ /* Check if we are done */ if(ielen < (offset + 4)) { /* We have a short IE. So we should assume TKIP/TKIP. */ printf(" Group Cipher : TKIP\n"); printf(" Pairwise Cipher : TKIP\n"); return; } /* Next we have our group cipher. */ if(memcmp(&iebuf[offset], wpa_oui, 3) != 0) { printf(" Group Cipher : Proprietary\n"); } else { printf(" Group Cipher :"); iw_print_value_name(iebuf[offset+3], iw_ie_cypher_name, IW_IE_CYPHER_NUM); printf("\n"); } offset += 4; /* Check if we are done */ if(ielen < (offset + 2)) { /* We don't have a pairwise cipher, or auth method. Assume TKIP. */ printf(" Pairwise Ciphers : TKIP\n"); return; } /* Otherwise, we have some number of pairwise ciphers. */ cnt = iebuf[offset] | (iebuf[offset + 1] << 8); offset += 2; printf(" Pairwise Ciphers (%d) :", cnt); if(ielen < (offset + 4*cnt)) return; for(i = 0; i < cnt; i++) { if(memcmp(&iebuf[offset], wpa_oui, 3) != 0) { printf(" Proprietary"); } else { iw_print_value_name(iebuf[offset+3], iw_ie_cypher_name, IW_IE_CYPHER_NUM); } offset+=4; } printf("\n"); /* Check if we are done */ if(ielen < (offset + 2)) return; /* Now, we have authentication suites. */ cnt = iebuf[offset] | (iebuf[offset + 1] << 8); offset += 2; printf(" Authentication Suites (%d) :", cnt); if(ielen < (offset + 4*cnt)) return; for(i = 0; i < cnt; i++) { if(memcmp(&iebuf[offset], wpa_oui, 3) != 0) { printf(" Proprietary"); } else { iw_print_value_name(iebuf[offset+3], iw_ie_key_mgmt_name, IW_IE_KEY_MGMT_NUM); } offset+=4; } printf("\n"); /* Check if we are done */ if(ielen < (offset + 1)) return; /* Otherwise, we have capabilities bytes. * For now, we only care about preauth which is in bit position 1 of the * first byte. (But, preauth with WPA version 1 isn't supposed to be * allowed.) 8-) */ if(iebuf[offset] & 0x01) { printf(" Preauthentication Supported\n"); } } /*------------------------------------------------------------------*/ /* * Process a generic IE and display the info in human readable form * for some of the most interesting ones. * For now, we only decode the WPA IEs. */ static inline void iw_print_gen_ie(unsigned char * buffer, int buflen) { int offset = 0; /* Loop on each IE, each IE is minimum 2 bytes */ while(offset <= (buflen - 2)) { //printf(" IE: "); LN2 co /* Check IE type */ switch(buffer[offset]) { case 0xdd: /* WPA1 (and other) */ case 0x30: /* WPA2 */ iw_print_ie_wpa(buffer + offset, buflen); break; default: ; //LN2 co //iw_print_ie_unknown(buffer + offset, buflen); } /* Skip over this IE to the next one in the list. */ offset += buffer[offset+1] + 2; } //printf("Finish\n"); //LN2 } #endif /* WE_ESSENTIAL */ ... ... ... /** * buf = "Quality=17/100 Signal_level=-61 dBm" */ static inline char **ssplit (char *buf) //LN2 { int i=0; char *delim = " "; char *pch; char **ptr = (char **)malloc(sizeof(char*) * 4); for (i = 0; i < 4; i++) ptr[i] = (char *)malloc(sizeof(char *) * 128); i=0; pch = strtok(buf,delim); while (pch != NULL) { strcpy(ptr[i], pch); pch = strtok (NULL, delim); ++i; } return ptr; } ... ... ... /*------------------------------------------------------------------*/ /* * Print one element from the scanning results */ static inline void print_scanning_token(struct stream_descr * stream, /* Stream of events */ struct iw_event * event, /* Extracted token */ struct iwscan_state * state, struct iw_range * iw_range, /* Range info */ int has_range) { char buffer[128]; /* Temporary buffer */ char **split_buf; /* Now, let's decode the event */ switch(event->cmd) { case SIOCGIWAP: if (FLAG) printf("Finish\n"); //LN2 printf(" Cell %02d - Address: %s\n", state->ap_num, iw_saether_ntop(&event->u.ap_addr, buffer)); state->ap_num++; break; case SIOCGIWNWID: if(event->u.nwid.disabled) printf(" NWID:off/any\n"); else printf(" NWID:%X\n", event->u.nwid.value); break; case SIOCGIWFREQ: { double freq; /* Frequency/channel */ int channel = -1; /* Converted to channel */ freq = iw_freq2float(&(event->u.freq)); /* Convert to channel if possible */ if(has_range) channel = iw_freq_to_channel(freq, iw_range); iw_print_freq(buffer, sizeof(buffer), freq, channel, event->u.freq.flags); printf(" %s\n", buffer); } break; case SIOCGIWMODE: /* Note : event->u.mode is unsigned, no need to check <= 0 */ if(event->u.mode >= IW_NUM_OPER_MODE) event->u.mode = IW_NUM_OPER_MODE; 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 SIOCGIWMODUL: { unsigned int modul = event->u.param.value; int i; int n = 0; printf(" Modulations :"); for(i = 0; i < IW_SIZE_MODUL_LIST; i++) { if((modul & iw_modul_list[i].mask) == iw_modul_list[i].mask) { if((n++ % 8) == 7) printf("\n "); else printf(" ; "); printf("%s", iw_modul_list[i].cmd); } } printf("\n"); } break; case IWEVQUAL: iw_print_stats(buffer, sizeof(buffer), &event->u.qual, iw_range, has_range); //printf(" %s\n", buffer); //LN2 co split_buf=ssplit(buffer); printf(" %s\n", split_buf[0]); //LN2 printf(" %s\n", split_buf[1]); free(split_buf[0]); free(split_buf[1]); free(split_buf[2]); free(split_buf[3]); free(split_buf); break; #ifndef WE_ESSENTIAL 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; #endif /* WE_ESSENTIAL */ 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) */ }
- parse.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #define SSID_SIZE 32 #define SECU_SIZE 128 #define AUTH_SIZE 16 #define SSID_NUMS 128 //print flag int P1SFLAG=0; int P2FLAG=0; int P2SFLAG=0; typedef struct winfo { char ssid[SSID_SIZE]; int quality; char secutity[SECU_SIZE]; char auth[AUTH_SIZE]; char key; }winfo_t; void print_list (winfo_t *wv, int ssflag); void analysis (char *buf, winfo_t *wv, int *flag); void wl_clear (winfo_t *wv); int wifi_list (const char *cmd); int fexists(const char* filename); int record_ssid (char **buf, winfo_t *info); /******************* * This function will limit it display to only one SSID *******************/ int record_ssid (char **buf, winfo_t *info) { static unsigned int i=0; unsigned int j=0; if ( strlen(*(buf)) == 0) { //printf("fisrt\n"); strcpy(*(buf), info->ssid); ++i; } else { for(j=0; j<i; j++) { if (strcmp(info->ssid, *(buf+j)) == 0) //repeat ssid return 1; } strcpy(*(buf+i), info->ssid); ++i; } return 0; } void print_list (winfo_t *wv, int ssflag) //same_ssid_flag { if (!strcmp("\"\"", wv->ssid)) return; if (ssflag) return; if (P1SFLAG) { if (wv->key == 0) printf("%s, %d, %s, none\n", wv->ssid, wv->quality, wv->key?"ON":"OFF"); else printf("%s, %d, %s, %s, %s\n", wv->ssid, wv->quality, wv->key?"ON":"OFF", wv->secutity, wv->auth); } else if (P2FLAG) { printf("%s\n", wv->ssid); printf("%d\n", wv->quality); printf("%s\n", wv->key?"ON":"OFF"); printf("---\n"); } else if (P2SFLAG) { printf("%s\n", wv->ssid); printf("%d\n", wv->quality); printf("%s\n", wv->key?"ON":"OFF"); if (wv->key == 0) printf("none\n"); else { printf("%s\n", wv->secutity); printf("%s\n", wv->auth); } printf("---\n"); } else //P1FLAG printf("%s, %d, %s\n", wv->ssid, wv->quality, wv->key?"ON":"OFF"); return; } void analysis (char *buf, winfo_t *wv, int *flag) { char *pch; char *delim; char tmp[SSID_SIZE]; //printf("%s_buf=%s, len=%ld\n", __FUNCTION__, buf, strlen(buf)); //Quality memset(tmp, '\0', sizeof(char)*SSID_SIZE); pch=strstr(buf, "Quality"); if ( pch != NULL) { pch=strchr(pch, '='); ++pch; strcpy(tmp, pch); delim = "/"; pch = strtok(tmp, delim); sscanf(pch, "%d", &wv -> quality); pch = strtok (NULL, delim); if(!strcmp("70", pch)) wv -> quality=abs(wv->quality*1.4); return; } //Encryption Key pch=strstr(buf, "Encryption"); if ( pch != NULL) { delim = ":"; pch = strtok(pch, delim); pch = strtok (NULL, delim); if(!strcmp("on", pch)) wv -> key=1; else wv -> key=0; return; } //ESSID pch=strstr(buf, "ESSID"); if ( pch != NULL) { delim = ":"; pch=strtok(pch, delim); pch=strtok(NULL, delim); if(strlen(pch)==2) //sometime, ESSID:"" { strncpy(wv->ssid, "\"\"", 2); return; } ++pch; if (strlen(pch) >= SSID_SIZE) strncpy(wv->ssid, pch, sizeof(char)*SSID_SIZE); else strncpy(wv->ssid, pch, strlen(pch)-1); return; } //MUST Protocol first //IE (Protocol) pch=strstr(buf, "Protocol"); if( pch != NULL) { return; } //IE (security) pch=strstr(buf, "IE"); if ( pch != NULL) { delim = ":"; pch = strtok(pch, delim); pch = strtok (NULL, delim); ++pch; if(strlen(wv->secutity) == 0) { strncpy(wv->secutity, pch, sizeof(char)*SECU_SIZE); } else { strcat(wv->secutity, "|"); strncat(wv->secutity, pch, SECU_SIZE-strlen(wv->secutity)-1); } return; } pch=strstr(buf, "Authentication"); if( pch != NULL) { delim = ":"; pch = strtok(pch, delim); pch = strtok (NULL, delim); ++pch; if(strlen(wv->auth) == 0) { strncpy(wv->auth, pch, sizeof(char)*AUTH_SIZE); } #if 0 // if only show at late one of auth is not enough, open else { strcat(wv->auth, "|"); strncat(wv->auth, pch, AUTH_SIZE-strlen(wv->auth)-1); } #endif } pch=strstr(buf, "Finish"); if ( pch != NULL) { *flag=1; return; } return; } void wl_clear (winfo_t *wv) { wv->key=-1; wv->quality=-1; memset(wv->ssid, '\0', sizeof(char)*SSID_SIZE); memset(wv->secutity, '\0', sizeof(char)*SECU_SIZE); memset(wv->auth, '\0', sizeof(char)*AUTH_SIZE); return; } int wifi_list (const char *cmd) { int i=0, j=0; FILE *pp=NULL; char buf[256]; int flag=0; int ret=0; char **ptr =(char **)malloc(sizeof(char*) * SSID_NUMS); for (i = 0; i <SSID_NUMS; i++) ptr[i] =(char *)malloc(sizeof(char *) * SSID_NUMS); for (i = 0; i <SSID_NUMS; i++) for(j=0; j< SSID_NUMS; j++) ptr[i][j]=0; winfo_t *pwvalue, wv; pwvalue=&wv; wl_clear(pwvalue); pp=popen(cmd, "r"); while (fgets(buf, 255, pp) != NULL) { buf[strlen(buf)-1]='\0'; //printf("buf=%s", buf); analysis(buf, pwvalue, &flag); //printf("i=%d, flag=%d, buf=%s\n", i, flag, buf); if ((i > 0 && flag)) { ret=record_ssid(ptr, pwvalue); print_list(pwvalue, ret); wl_clear(pwvalue); flag=0; i=0; } ++i; } if(flag==0) //if only one data; only one SSID info { ret=record_ssid(ptr, pwvalue); print_list(pwvalue, ret); } for(j=0; j< SSID_NUMS; j++) free(ptr[j]); free(ptr); pclose(pp); return 0; } /* * Check if a file exist using stat() function * return 0 if the file exist otherwise return 1 */ int fexists(const char* filename){ struct stat buffer; int exist = stat(filename,&buffer); if(exist == 0) return 0; else return 1; } int main (int argc, char *argv[]) { int i=0; char wiface[8]={0}; char wcmd1[128]={0}; char *wcmd2="scanning | grep -e ESSID -e Quality -e Encryption -e IE -e Authentication -e Finish"; for(i=1; i<argc; i++) { if(argv[i] != NULL) { if ( !(strcmp(argv[i], "-i")) || !(strcmp(argv[i], "--interface")) ) { if (argv[i+1] == NULL) { printf("enter an interface name, ex:wlan0\n"); return 1; } strcpy(wiface, argv[i+1]); ++i; continue; } else if ( !(strcmp(argv[i], "-p1s")) ) P1SFLAG=1; else if ( !(strcmp(argv[i], "-p2")) ) P2FLAG=1; else if ( !(strcmp(argv[i], "-p2s")) ) P2SFLAG=1; else if (!(strcmp(argv[i], "-h")) || !(strcmp(argv[i], "--help")) ) { printf("Useage:\n"); printf(" -i or --interface, wifi interface, default:wlan0\n"); printf(" -p1s, , print security\n"); printf(" -p2, , \n"); printf(" -p2s, , print security\n"); printf(" -h or --help , help\n"); printf("[Note]: The number of SSIDs can't not more than 128\n"); return 0; } else { printf("???, argv[%d]=%s\n", i, argv[i]); return 0; } } } //wifi_list("/home/ubuntu/Open_Source/wireless-tools/wireless-tools_modify/iwlist_era wlp3s0 scanning | grep -e ESSID -e Quality -e Encryption -e IE -e Finish"); //wifi_list("/home/ubuntu/Open_Source/wireless-tools/wireless-tools_modify/iwlist_era wlp3s0 scanning | grep -e ESSID -e Quality -e Encryption -e IE -e Authentication -e Finish"); if (fexists("/usr/local/sbin/iwlist_era")) { printf("iwlist_era, command_not_found\n"); return 1; } if (strlen(wiface) > 0) { strcpy(wcmd1, "iwlist_era "); strcat(wcmd1, wiface); strcat(wcmd1, " "); strcat(wcmd1, wcmd2); } else { strcpy(wcmd1, "iwlist_era "); strcat(wcmd1, "wlan0"); strcat(wcmd1, " "); strcat(wcmd1, wcmd2); } wifi_list(wcmd1); return 0; }
沒有留言:
張貼留言