static int get80211priv(const char *ifname, int op, void *data, size_t len) { struct iwreq iwr; if (do80211priv(&iwr, ifname, op, data, len) < 0) return -1; if (len < IFNAMSIZ) memcpy(data, iwr.u.name, len); return iwr.u.data.length; }
static struct wifi_channels *list_channelsext(const char *ifname, int allchans) { struct ieee80211req_chaninfo chans; struct ieee80211req_chaninfo achans; const struct ieee80211_channel *c; int i; fprintf(stderr, "list channels for %s\n", ifname); if (do80211priv (ifname, IEEE80211_IOCTL_GETCHANINFO, &chans, sizeof(chans)) < 0) { fprintf(stderr, "unable to get channel information\n"); return NULL; } if (!allchans) { uint8_t active[64]; if (do80211priv (ifname, IEEE80211_IOCTL_GETCHANLIST, &active, sizeof(active)) < 0) { fprintf(stderr, "unable to get active channel list\n"); return NULL; } memset(&achans, 0, sizeof(achans)); for (i = 0; i < chans.ic_nchans; i++) { c = &chans.ic_chans[i]; if (isset(active, c->ic_ieee) || allchans) achans.ic_chans[achans.ic_nchans++] = *c; } } else achans = chans; struct wifi_channels *list = (struct wifi_channels *)safe_malloc(sizeof(struct wifi_channels) * (achans.ic_nchans + 1)); (void)memset(list, 0, (sizeof(struct wifi_channels)*((achans.ic_nchans + 1)))); char wl_mode[16]; char wl_turbo[16]; sprintf(wl_mode, "%s_net_mode", ifname); sprintf(wl_turbo, "%s_channelbw", ifname); int l = 0; int up = 0; char sb[32]; sprintf(sb, "%s_nctrlsb", ifname); if (nvram_match(sb, "upper")) up = 1; for (i = 0; i < achans.ic_nchans; i++) { #ifdef HAVE_BUFFALO if (achans.ic_chans[i].ic_flags & IEEE80211_CHAN_RADARFOUND) //filter channels with detected radar continue; #endif // filter out A channels if mode isnt A-Only or mixed if (IEEE80211_IS_CHAN_5GHZ(&achans.ic_chans[i])) { if (nvram_invmatch(wl_mode, "a-only") && nvram_invmatch(wl_mode, "mixed") && nvram_invmatch(wl_mode, "n5-only") && nvram_invmatch(wl_mode, "na-only")) { // fprintf(stderr,"5 Ghz %d is not compatible to a-only/mixed/na-only %X\n",achans.ic_chans[i].ic_freq,achans.ic_chans[i].ic_flags); continue; } if (nvram_match(wl_turbo, "40") && (nvram_match(wl_mode, "n5-only") || nvram_match(wl_mode, "mixed") || nvram_match(wl_mode, "na-only"))) { if (up && !IEEE80211_IS_CHAN_11NA_HT40PLUS (&achans.ic_chans[i])) continue; if (!up && !IEEE80211_IS_CHAN_11NA_HT40MINUS (&achans.ic_chans[i])) continue; } } // filter out B/G channels if mode isnt g-only, b-only or mixed if (IEEE80211_IS_CHAN_2GHZ(&achans.ic_chans[i])) { if (nvram_invmatch(wl_mode, "g-only") && nvram_invmatch(wl_mode, "mixed") && nvram_invmatch(wl_mode, "b-only") && nvram_invmatch(wl_mode, "n2-only") && nvram_invmatch(wl_mode, "bg-mixed") && nvram_invmatch(wl_mode, "ng-only")) { fprintf(stderr, "%s:%d\n", __func__, __LINE__); continue; } #ifdef HAVE_BUFFALO_SA if(nvram_default_match("region", "SA", "") && (!strcmp(getUEnv("region"), "AP") || !strcmp(getUEnv("region"), "US")) && achans.ic_chans[i].ic_ieee > 11 && achans.ic_chans[i].ic_ieee <= 14) continue; #endif if (nvram_match(wl_turbo, "40") && (nvram_match(wl_mode, "n2-only") || nvram_match(wl_mode, "mixed") || nvram_match(wl_mode, "ng-only"))) { if (up && !IEEE80211_IS_CHAN_11NG_HT40PLUS (&achans.ic_chans[i])) { fprintf(stderr, "%s:%d\n", __func__, __LINE__); continue; } if (!up && !IEEE80211_IS_CHAN_11NG_HT40MINUS (&achans.ic_chans[i])) { fprintf(stderr, "%s:%d\n", __func__, __LINE__); continue; } } } list[l].channel = achans.ic_chans[i].ic_ieee; list[l].freq = achans.ic_chans[i].ic_freq; list[l].noise = -95; // achans.ic_chans[i].ic_noise; l++; } list[l].freq = -1; return list; }
int site_survey_main(int argc, char *argv[]) { char *name = nvram_safe_get("wl0_ifname"); unsigned char mac[20]; int i = 0; char *dev = name; unlink(SITE_SURVEY_DB); int ap = 0, oldap = 0; unsigned char buf[24 * 1024]; char ssid[31]; unsigned char *cp; int len; system2("airoscan-ng wifi0"); len = do80211priv("ath0", IEEE80211_IOCTL_SCAN_RESULTS, buf, sizeof(buf)); if (len == -1) fprintf(stderr, "unable to get scan results"); if (len < sizeof(struct ieee80211req_scan_result)) return; cp = buf; do { struct ieee80211req_scan_result *sr; unsigned char *vp; char ssid[14]; sr = (struct ieee80211req_scan_result *)cp; vp = (u_int8_t *)(sr + 1); memset(ssid, 0, sizeof(ssid)); strncpy(site_survey_lists[i].SSID, vp, sr->isr_ssid_len); strcpy(site_survey_lists[i].BSSID, ieee80211_ntoa(sr->isr_bssid)); site_survey_lists[i].channel = ieee80211_mhz2ieee(sr->isr_freq); site_survey_lists[i].frequency = sr->isr_freq; int noise = 256; noise -= (int)sr->isr_noise; site_survey_lists[i].phy_noise = -noise; site_survey_lists[i].RSSI = (int)site_survey_lists[i].phy_noise + (int)sr->isr_rssi; site_survey_lists[i].capability = sr->isr_capinfo; site_survey_lists[i].rate_count = sr->isr_nrates; cp += sr->isr_len, len -= sr->isr_len; i++; } while (len >= sizeof(struct ieee80211req_scan_result)); write_site_survey(); open_site_survey(); for (i = 0; i < SITE_SURVEY_NUM && site_survey_lists[i].BSSID[0] && site_survey_lists[i].channel != 0; i++) { fprintf(stderr, "[%2d] SSID[%20s] BSSID[%s] channel[%2d] frequency[%4d] rssi[%d] noise[%d] beacon[%d] cap[%x] dtim[%d] rate[%d]\n", i, site_survey_lists[i].SSID, site_survey_lists[i].BSSID, site_survey_lists[i].channel, site_survey_lists[i].frequency, site_survey_lists[i].RSSI, site_survey_lists[i].phy_noise, site_survey_lists[i].beacon_period, site_survey_lists[i].capability, site_survey_lists[i].dtim_period, site_survey_lists[i].rate_count); } return 0; }