char *get_monitor(void) { char *ifname = nvram_safe_get("wifi_display"); #ifdef HAVE_ATH9K if (is_ath9k(ifname)) return "mon.ath0"; else #endif { int devcount; sscanf( ifname, "ath%d", &devcount ); static char mon[32]; sprintf(mon,"mon%d",devcount); return mon; } }
int main(int argc, char **argv) { char *dev; int oldMonitor, newMonitor; u_char packet[4096]; int pktlen; wiviz_cfg cfg; int i; int defaultHopSeq[] = { 1, 3, 6, 8, 11 }; int s, one; memset(&cfg, 0, sizeof(cfg)); #ifdef HAVE_RT2880 wl_dev = "ra0"; #elif HAVE_MADWIFI wl_dev = nvram_safe_get("wifi_display"); #else char tmp[32]; sprintf(tmp, "%s_ifname", nvram_safe_get("wifi_display")); wl_dev = nvram_safe_get(tmp); #endif if (argc > 1) if (!strcmp(argv[1], "terminate")) { #ifdef HAVE_MADWIFI // return to original channel #ifdef HAVE_ATH9K if (!is_ath9k(wl_dev)) #endif { sysprintf("iwconfig %s channel %sM", get_monitor(), nvram_nget("%s_channel", nvram_safe_get("wifi_display"))); sleep(1); sysprintf("ifconfig %s down", get_monitor()); if (is_ar5008(nvram_safe_get("wifi_display"))) { sysprintf("80211n_wlanconfig %s destroy", get_monitor()); } else { sysprintf("wlanconfig %s destroy", get_monitor()); } } #elif HAVE_RT2880 nvram_set("wl0_mode", nvram_safe_get("wl0_oldmode")); sysprintf("startservice configurewifi"); if (nvram_match("wl0_mode", "sta") || nvram_match("wl0_mode", "apsta")) { sysprintf("startstop wan"); } #else oldMonitor = 0; wl_ioctl(wl_dev, WLC_SET_MONITOR, &oldMonitor, 4); #endif return 0; } global_cfg = &cfg; signal(SIGUSR1, &signal_handler); signal(SIGUSR2, &signal_handler); printf("Wi-Viz 2 infogathering daemon by Nathan True\n"); printf("http://wiviz.natetrue.com\n"); memset(&cfg, 0, sizeof(wiviz_cfg)); cfg.numHosts = 0; cfg.lastKeepAlive = time(NULL); cfg.channelHopping = 0; cfg.channelDwellTime = 1000; cfg.channelHopSeqLen = 5; memcpy(cfg.channelHopSeq, defaultHopSeq, sizeof(defaultHopSeq)); #if !defined(HAVE_MADWIFI) && !defined(HAVE_RT2880) wl_ioctl(wl_dev, WLC_GET_MAGIC, &i, 4); if (i != WLC_IOCTL_MAGIC) { printf("Wireless magic not correct, not querying wl for info %X!=%X\n", i, WLC_IOCTL_MAGIC); cfg.readFromWl = 0; } else { cfg.readFromWl = 1; wl_ioctl(wl_dev, WLC_GET_MONITOR, &oldMonitor, 4); newMonitor = 1; wl_ioctl(wl_dev, WLC_SET_MONITOR, &newMonitor, 4); } #elif HAVE_RT2880 nvram_set("wl0_oldmode", nvram_safe_get("wl0_mode")); nvram_set("wl0_mode", "sta"); if (!nvram_match("wl0_oldmode", "sta")) sysprintf("startservice configurewifi"); sysprintf("iwconfig ra0 mode monitor"); cfg.readFromWl = 1; #else #ifdef HAVE_ATH9K if (!is_ath9k(nvram_safe_get("wifi_display"))) #endif { if (is_ar5008(nvram_safe_get("wifi_display"))) { sysprintf("80211n_wlanconfig %s create wlandev %s wlanmode monitor", get_monitor(), getWifi(nvram_safe_get("wifi_display"))); } else { sysprintf("wlanconfig %s create wlandev %s wlanmode monitor", get_monitor(), getWifi(nvram_safe_get("wifi_display"))); } sysprintf("ifconfig %s up", get_monitor()); } cfg.readFromWl = 1; #endif reloadConfig(); #if defined(HAVE_MADWIFI) || defined(HAVE_RT2880) s = openMonitorSocket(get_monitor()); // for testing we use ath0 #else if (nvram_match("wifi_display", "wl1")) s = openMonitorSocket("prism1"); else s = openMonitorSocket("prism0"); #endif if (s == -1) return; one = 1; ioctl(s, FIONBIO, (char *)&one); if (cfg.readFromWl) { readWL(&cfg); } #ifdef WIVIZ_GPS gps_init(&cfg); #endif while (!stop) { #ifdef WIVIZ_GPS gps_tick(); #else if (time(NULL) - cfg.lastKeepAlive > 30) stop = 1; #endif pktlen = recv(s, packet, 4096, 0); if (pktlen <= 0) continue; dealWithPacket(&cfg, pktlen, packet); } signal_handler(SIGUSR1); if (cfg.channelHopperPID) kill(cfg.channelHopperPID, SIGKILL); #ifndef WIVIZ_GPS for (i = 0; i < MAX_HOSTS; i++) { print_host(stderr, cfg.hosts + i); if (cfg.hosts[i].occupied) printf("\n"); if (cfg.hosts[i].apInfo) free(cfg.hosts[i].apInfo); if (cfg.hosts[i].staInfo) free(cfg.hosts[i].staInfo); } #endif close(s); return 0; }
void dealWithPacket(wiviz_cfg * cfg, int pktlen, const u_char * packet) { ieee802_11_hdr *hWifi; wiviz_host *host; wiviz_host *emergebss; host_type type = typeUnknown; int wfType; int rssi = 0; int to_ds, from_ds; ieee_802_11_tag *e; ieee_802_11_mgt_frame *m; unsigned char *src; // = "\0\0\0\0\0\0"; unsigned char *dst; // = "\0\0\0\0\0\0"; unsigned char *bss; // = "\0\0\0\0\0\0"; char *ssid = ""; int channel = 0; int adhocbeacon = 0; u_char ssidlen = 0; ap_enc_type encType = aetUnknown; if (!packet) return; src = i_src; dst = i_dst; bss = i_bss; #ifdef HAVE_ATH9K if (is_ath9k(nvram_safe_get("wifi_display"))) { if (packet[0] > 0) { printf("Wrong radiotap header version.\n"); return; } else printf("ver %d\n", packet[0]); int number = packet[2] | (unsigned int)((unsigned int)packet[3] << 8); printf("num %d\n", number); if (number <= 0 || number >= pktlen) { printf("something wrong %d\n", number); return; } int noise = packet[number - 3]; rssi = -(100 - (packet[number - 4] - noise)); printf("rssi %d\n", rssi); hWifi = (ieee802_11_hdr *) (packet + (number)); } else #endif { prism_hdr *hPrism; prism_did *i; if (pktlen < sizeof(prism_hdr) + (sizeof(ieee802_11_hdr))) return; hPrism = (prism_hdr *) packet; if (pktlen < hPrism->msg_length + (sizeof(ieee802_11_hdr))) return; // bogus packet hWifi = (ieee802_11_hdr *) (packet + (hPrism->msg_length)); i = (prism_did *) ((char *)hPrism + sizeof(prism_hdr)); //Parse the prism DIDs #ifdef HAVE_MADWIFI int received = 0; while ((int)i < (int)hWifi) { if (i->did == pdn_rssi) { received = 1; rssi = i->data; } if (i->did == pdn_signal) { rssi = (int)i->data + rssi; } if (i->did == 0) //skip bogus empty value from atheros sequence counter { i = (prism_did *) (((unsigned char *)&i->data) + 4); } else { i = (prism_did *) (((unsigned char *)&i->data) + i->length); } } if (!received) // bogus, no prism data return; if (!rssi) // no rssi? can't be a packet return; #else while ((int)i < (int)hWifi) { if (i->did == pdn_rssi) rssi = *(int *)(i + 1); i = (prism_did *) ((int)(i + 1) + i->length); } #endif } memset(bss, 0, 6); memset(src, 0, 6); memset(dst, 0, 6); int fctype = (hWifi->frame_control & 0xC); int fc = (hWifi->frame_control & 0xf0); type = typeUnknown; printf("type %X, fc %X\n", fctype, fc); if (!fctype) // only accept management frames (type 0) { switch (fc) { //case mgt_assocRequest: //fc = 0 can be a broken frame too, no check possible here case mgt_reassocRequest: case mgt_probeRequest: type = typeSta; src = hWifi->addr2; dst = hWifi->addr1; break; case mgt_assocResponse: case mgt_reassocResponse: case mgt_probeResponse: case mgt_beacon: src = hWifi->addr2; dst = hWifi->addr1; bss = hWifi->addr3; type = typeAP; break; } #ifdef DEBUG fprintf(stderr, "fc: %X", hWifi->frame_control); fprintf(stderr, " src:"); fprintf(stderr, "%s", ntoa(src)); fprintf(stderr, " dst:"); fprintf(stderr, "%s", ntoa(dst)); fprintf(stderr, " bss:"); fprintf(stderr, "%s\n", ntoa(src)); #endif } to_ds = hWifi->flags & IEEE80211_TO_DS; from_ds = hWifi->flags & IEEE80211_FROM_DS; unsigned char subtype = hWifi->frame_control & 0xF0; if (fctype == 0x8 && subtype == 0) { //Data frame src = hWifi->addr2; dst = hWifi->addr1; if (!from_ds) type = typeSta; else if (from_ds && to_ds) type = typeWDS; else type = typeAP; if (!to_ds && !from_ds) bss = hWifi->addr3; if (to_ds && !from_ds) bss = hWifi->addr1; if (!to_ds && from_ds) bss = hWifi->addr2; if (to_ds && from_ds) bss = hWifi->addr1; // wds frame #ifdef DEBUG fprintf(stderr, "addr1:"); fprintf(stderr, "%s", ntoa(hWifi->addr1)); fprintf(stderr, " addr2:"); fprintf(stderr, "%s", ntoa(hWifi->addr2)); fprintf(stderr, " addr3:"); fprintf(stderr, "%s", ntoa(hWifi->addr3)); fprintf(stderr, " bss:"); fprintf(stderr, "%s\n", ntoa(bss)); #endif } if (type == typeUnknown) return; //Parse the 802.11 tags if (!fctype && (fc == mgt_probeResponse || fc == mgt_beacon || fc == mgt_probeRequest)) { m = (ieee_802_11_mgt_frame *) (hWifi + 1); if (swap16(m->caps) & MGT_CAPS_IBSS) { type = typeSta; adhocbeacon = 1; } if (swap16(m->caps) & MGT_CAPS_WEP) encType = aetEncWEP; else encType = aetUnencrypted; e = (ieee_802_11_tag *) ((int)m + sizeof(ieee_802_11_mgt_frame)); while ((u_int) e < (u_int) packet + pktlen) { if (e->tag == tagSSID) { ssidlen = e->length; ssid = (char *)(e + 1); } if (e->tag == tagChannel) { channel = *(char *)(e + 1); } if (e->tag == tagRSN) { if (encType != aetEncWPAmix) { if (encType == aetEncWPA) encType = aetEncWPAmix; else encType = aetEncWPA2; } } if (e->tag == tagVendorSpecific) { if (e->length >= 4 && memcmp(e + 1, "\x00\x50\xf2\x01", 4) == 0) { //WPA encryption if (encType != aetEncWPAmix) { if (encType == aetEncWPA2) encType = aetEncWPAmix; else encType = aetEncWPA; } } if (e->length >= 4 && memcmp(e + 1, "\x00\x0f\xac\x01", 4) == 0) { //WPA2 encryption if (encType != aetEncWPAmix) { if (encType == aetEncWPA) encType = aetEncWPAmix; else encType = aetEncWPA2; } } } e = (ieee_802_11_tag *) ((int)(e + 1) + e->length); } } //Look up the host in the hash table host = gotHost(cfg, src, type); //Add any info we received if (host->RSSI) { host->RSSI = host->RSSI * 9 / 10 + (-rssi * 10); } else { host->RSSI = -rssi * 100; } if (type == typeSta) { if (nonzeromac(bss)) { memcpy(host->staInfo->connectedBSSID, bss, 6); host->staInfo->state = ssAssociated; emergebss = gotHost(cfg, bss, typeAP); if (emergebss->RSSI == 0) emergebss->RSSI = 10000; memcpy(emergebss->apInfo->bssid, bss, 6); if (adhocbeacon) { emergebss->type = typeAdhocHub; if (ssidlen > 0 && ssidlen <= 32) { memcpy(emergebss->apInfo->ssid, ssid, ssidlen); emergebss->apInfo->ssidlen = ssidlen; } if (channel) emergebss->apInfo->channel = channel; emergebss->apInfo->flags = hWifi->flags; emergebss->RSSI = host->RSSI; if (encType != aetUnknown) emergebss->apInfo->encryption = encType; } } if (!fctype && fc == mgt_probeRequest && host->staInfo->state == ssUnknown) host->staInfo->state = ssUnassociated; if (!fctype && fc == mgt_probeRequest && ssidlen > 0 && ssidlen <= 32) { memcpy(host->staInfo->lastssid, ssid, ssidlen); host->staInfo->lastssid[ssidlen] = 0; host->staInfo->lastssidlen = ssidlen; } } if (type == typeWDS) { if (nonzeromac(bss)) { memcpy(host->apInfo->bssid, bss, 6); } } if (type == typeAP) { if (nonzeromac(bss)) { memcpy(host->apInfo->bssid, bss, 6); } if (ssidlen > 0 && ssidlen <= 32) { memcpy(host->apInfo->ssid, ssid, ssidlen); host->apInfo->ssid[ssidlen] = 0; host->apInfo->ssidlen = ssidlen; } if (channel) host->apInfo->channel = channel; host->apInfo->flags = hWifi->flags; if (encType != aetUnknown) host->apInfo->encryption = encType; } }