static int wext_get_mode(const char *ifname, int *buf) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWMODE, &wrq) >= 0) { switch(wrq.u.mode) { case 1: *buf = IWINFO_OPMODE_ADHOC; break; case 2: *buf = IWINFO_OPMODE_CLIENT; break; case 3: *buf = IWINFO_OPMODE_MASTER; break; case 6: *buf = IWINFO_OPMODE_MONITOR; break; default: *buf = IWINFO_OPMODE_UNKNOWN; break; } return 0; } return -1; }
int wext_get_freqlist(const char *ifname, char *buf, int *len) { struct iwreq wrq; struct iw_range range; struct iwinfo_freqlist_entry entry; int i, bl; wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if(wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) { bl = 0; for(i = 0; i < range.num_frequency; i++) { entry.mhz = wext_freq2mhz(&range.freq[i]); entry.channel = range.freq[i].i; entry.restricted = 0; memcpy(&buf[bl], &entry, sizeof(struct iwinfo_freqlist_entry)); bl += sizeof(struct iwinfo_freqlist_entry); } *len = bl; return 0; } return -1; }
int wext_get_noise(const char *ifname, int *buf) { struct iwreq wrq; struct iw_statistics stats; wrq.u.data.pointer = (caddr_t) &stats; wrq.u.data.length = sizeof(struct iw_statistics); wrq.u.data.flags = 1; if(wext_ioctl(ifname, SIOCGIWSTATS, &wrq) >= 0) { *buf = (stats.qual.updated & IW_QUAL_DBM) ? (stats.qual.noise - 0x100) : stats.qual.noise; if (*buf == 0) { *buf = 10; } return 0; } return -1; /* *buf = 10; return 0; */ }
int wext_probe(const char *ifname) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWNAME, &wrq) >= 0) return 1; return 0; }
int wext_get_channel(const char *ifname, int *buf) { struct iwreq wrq; struct iw_range range; double freq; int i; if(wext_ioctl(ifname, SIOCGIWFREQ, &wrq) >= 0) { if( wrq.u.freq.m >= 1000 ) { freq = wext_freq2float(&wrq.u.freq); wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if(wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) { for(i = 0; i < range.num_frequency; i++) { if( wext_freq2float(&range.freq[i]) == freq ) { *buf = range.freq[i].i; return 0; } } } } else { *buf = wrq.u.freq.m; return 0; } } return -1; /* char cmd[256]; sprintf(cmd, "iwlist %s channel | grep 'Current Channel' | awk -F':' '{print $2}'", ifname); FILE *fp = popen(cmd, "r"); fscanf(fp, "%d\n", buf); pclose(fp); return 0; */ }
int wext_get_bitrate(const char *ifname, int *buf) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWRATE, &wrq) >= 0) { *buf = (wrq.u.bitrate.value / 1000); return 0; } return -1; }
int wext_get_ssid(const char *ifname, char *buf) { struct iwreq wrq; wrq.u.essid.pointer = (caddr_t) buf; wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1; wrq.u.essid.flags = 0; if(wext_ioctl(ifname, SIOCGIWESSID, &wrq) >= 0) return 0; return -1; }
int wext_get_channel(const char *ifname, int *buf) { struct iwreq wrq; struct iw_range range; double freq; int i; if(wext_ioctl(ifname, SIOCGIWFREQ, &wrq) >= 0) { if( wrq.u.freq.m >= 1000 ) { freq = wext_freq2float(&wrq.u.freq); wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if(wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) { for(i = 0; i < range.num_frequency; i++) { if( wext_freq2float(&range.freq[i]) == freq ) { *buf = range.freq[i].i; return 0; } } } } else { *buf = wrq.u.freq.m; return 0; } } return -1; }
int wext_get_frequency(const char *ifname, int *buf) { struct iwreq wrq; struct iw_range range; int i, channel; if(wext_ioctl(ifname, SIOCGIWFREQ, &wrq) >= 0) { /* We got a channel number instead ... */ if( wrq.u.freq.m < 1000 ) { channel = wrq.u.freq.m; wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if(wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) { for(i = 0; i < range.num_frequency; i++) { if( range.freq[i].i == channel ) { *buf = wext_freq2mhz(&range.freq[i]); return 0; } } } } else { *buf = wext_freq2mhz(&wrq.u.freq); return 0; } } return -1; }
int wext_get_bssid(const char *ifname, char *buf) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWAP, &wrq) >= 0) { sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (uint8_t)wrq.u.ap_addr.sa_data[0], (uint8_t)wrq.u.ap_addr.sa_data[1], (uint8_t)wrq.u.ap_addr.sa_data[2], (uint8_t)wrq.u.ap_addr.sa_data[3], (uint8_t)wrq.u.ap_addr.sa_data[4], (uint8_t)wrq.u.ap_addr.sa_data[5]); return 0; } return -1; }
int wext_get_quality(const char *ifname, int *buf) { struct iwreq wrq; struct iw_statistics stats; wrq.u.data.pointer = (caddr_t) &stats; wrq.u.data.length = sizeof(struct iw_statistics); wrq.u.data.flags = 1; if(wext_ioctl(ifname, SIOCGIWSTATS, &wrq) >= 0) { *buf = stats.qual.qual; return 0; } return -1; }
int wext_get_quality_max(const char *ifname, int *buf) { struct iwreq wrq; struct iw_range range; wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if(wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) { *buf = range.max_qual.qual; return 0; } return -1; }
int wext_get_mode(const char *ifname, char *buf) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWMODE, &wrq) >= 0) { switch(wrq.u.mode) { case 0: sprintf(buf, "Auto"); break; case 1: sprintf(buf, "Ad-Hoc"); break; case 2: sprintf(buf, "Client"); break; case 3: sprintf(buf, "Master"); break; case 4: sprintf(buf, "Repeater"); break; case 5: sprintf(buf, "Secondary"); break; case 6: sprintf(buf, "Monitor"); break; default: sprintf(buf, "Unknown"); } return 0; } return -1; }
int wext_get_txpower(const char *ifname, int *buf) { struct iwreq wrq; wrq.u.txpower.flags = 0; if(wext_ioctl(ifname, SIOCGIWTXPOW, &wrq) >= 0) { if(wrq.u.txpower.flags & IW_TXPOW_MWATT) *buf = iwinfo_mw2dbm(wrq.u.txpower.value); else *buf = wrq.u.txpower.value; return 0; } return -1; }
static int wext_get_txpower(const char *ifname, int *buf) { struct iwreq wrq; wrq.u.txpower.flags = 0; if(wext_ioctl(ifname, SIOCGIWTXPOW, &wrq) >= 0) { printf("##__ %s, %d, ifname = %s __##\n",__FILE__, __LINE__, ifname); if(wrq.u.txpower.flags & IW_TXPOW_MWATT) *buf = iwinfo_mw2dbm(wrq.u.txpower.value); else *buf = wrq.u.txpower.value; printf("##__ %s, %d, *buf = %d __##\n",__FILE__, __LINE__, *buf); return 0; } return -1; }
int wext_get_txpwrlist(const char *ifname, char *buf, int *len) { struct iwreq wrq; struct iw_range range; struct iwinfo_txpwrlist_entry entry; int i; wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if( (wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) && (range.num_txpower > 0) && (range.num_txpower <= IW_MAX_TXPOWER) && !(range.txpower_capa & IW_TXPOW_RELATIVE) ) { for( i = 0; i < range.num_txpower; i++ ) { if( range.txpower_capa & IW_TXPOW_MWATT ) { entry.dbm = iwinfo_mw2dbm(range.txpower[i]); entry.mw = range.txpower[i]; } /* Madwifi does neither set mW not dBm caps, also iwlist assumes * dBm if mW is not set, so don't check here... */ else /* if( range.txpower_capa & IW_TXPOW_DBM ) */ { entry.dbm = range.txpower[i]; entry.mw = iwinfo_dbm2mw(range.txpower[i]); } memcpy(&buf[i*sizeof(entry)], &entry, sizeof(entry)); } *len = i * sizeof(entry); return 0; } return -1; }
int wext_get_ssid(const char *ifname, char *buf) { struct iwreq wrq; wrq.u.essid.pointer = (caddr_t) buf; wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1; wrq.u.essid.flags = 0; if(wext_ioctl(ifname, SIOCGIWESSID, &wrq) >= 0) return 0; return -1; /* char cmd[256]; sprintf(cmd, "iwconfig %s | grep ESSID | awk -F':' '{print $2}' | sed 's/\\\"//g'", ifname); FILE *fp = popen(cmd, "r"); fscanf(fp, "%s\n", buf); pclose(fp); return 0; */ }
int wext_get_bitrate(const char *ifname, int *buf) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWRATE, &wrq) >= 0) { *buf = (wrq.u.bitrate.value / 1000); return 0; } return -1; /* char cmd[256]; sprintf(cmd, "iwconfig %s | grep 'Bit Rate' | awk -F'[:=]' '{print $2}'", ifname); FILE *fp = popen(cmd, "r"); fscanf(fp, "%d\n", buf); pclose(fp); *buf = (*buf) * 1024; return 0; */ }
int wext_get_bssid(const char *ifname, char *buf) { struct iwreq wrq; if(wext_ioctl(ifname, SIOCGIWAP, &wrq) >= 0) { sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", (uint8_t)wrq.u.ap_addr.sa_data[0], (uint8_t)wrq.u.ap_addr.sa_data[1], (uint8_t)wrq.u.ap_addr.sa_data[2], (uint8_t)wrq.u.ap_addr.sa_data[3], (uint8_t)wrq.u.ap_addr.sa_data[4], (uint8_t)wrq.u.ap_addr.sa_data[5]); return 0; } return -1; /* char cmd[256]; FILE *fp = NULL; sprintf(cmd, "ifconfig %s | grep UP", ifname); fp = popen(cmd, "r"); fscanf(fp, "%s\n", buf); pclose(fp); if(strlen(buf)<2) { sprintf(buf, "00:00:00:00:00:00"); return 0; } sprintf(cmd, "iwconfig %s | grep -Eo [:0-9A-F:]{2}\\(\\:[:0-9A-F:]{2}\\){5}", ifname); fp = popen(cmd, "r"); fscanf(fp, "%s\n", buf); pclose(fp); return 0; */ }
int wext_get_scanlist(const char *ifname, char *buf, int *len) { struct iwreq wrq; struct iw_scan_req scanopt; /* Options for 'set' */ unsigned char *buffer = NULL; /* Results */ int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */ struct iw_range range; int has_range = 1; struct timeval tv; /* Select timeout */ int timeout = 15000000; /* 15s */ int entrylen = 0; struct iwinfo_scanlist_entry e; wrq.u.data.pointer = (caddr_t) ⦥ wrq.u.data.length = sizeof(struct iw_range); wrq.u.data.flags = 0; if( wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0 ) { /* Init timeout value -> 250ms between set and first get */ tv.tv_sec = 0; tv.tv_usec = 250000; /* Clean up set args */ memset(&scanopt, 0, sizeof(scanopt)); wrq.u.data.pointer = NULL; wrq.u.data.flags = 0; wrq.u.data.length = 0; /* Initiate Scanning */ if( wext_ioctl(ifname, SIOCSIWSCAN, &wrq) >= 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; 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); 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( wext_ioctl(ifname, SIOCGIWSCAN, &wrq) ) { /* 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); return -1; } else { /* We have the results, go to process them */ break; } } } if( wrq.u.data.length ) { struct iw_event iwe; struct stream_descr stream; int ret; int first = 1; memset(&stream, 0, sizeof(stream)); stream.current = (char *)buffer; stream.end = (char *)buffer + wrq.u.data.length; do { /* Extract an event and print it */ ret = wext_extract_event(&stream, &iwe, range.we_version_compiled); if(ret >= 0) { if( (iwe.cmd == SIOCGIWAP) || (ret == 0) ) { if( first ) { first = 0; } else if( (entrylen + sizeof(struct iwinfo_scanlist_entry)) <= IWINFO_BUFSIZE ) { /* if encryption is off, clear the crypto strunct */ if( !e.crypto.enabled ) memset(&e.crypto, 0, sizeof(struct iwinfo_crypto_entry)); memcpy(&buf[entrylen], &e, sizeof(struct iwinfo_scanlist_entry)); entrylen += sizeof(struct iwinfo_scanlist_entry); } else { /* we exceed the callers buffer size, abort here ... */ break; } memset(&e, 0, sizeof(struct iwinfo_scanlist_entry)); } wext_fill_entry(&stream, &iwe, &range, has_range, &e); } } while(ret > 0); free(buffer); *len = entrylen; return 0; } *len = 0; free(buffer); return 0; } } return -1; }