static int parse_elem_vendor(const unsigned char *e, const int l) { const struct ieee80211_ie_wpa *wpa = (const struct ieee80211_ie_wpa *) e; if (l < 5) return 0; if (memcmp(wpa->wpa_oui, "\x00\x50\xf2", 3) != 0) return 0; if (l < 8) return 0; if (wpa->wpa_type != WPA_OUI_TYPE) return 0; return parse_rsn((unsigned char *) &wpa->wpa_version, l - 6, 0); }
static void process_beacon(struct ieee80211_frame * wh, int totlen) { REQUIRE(wh != NULL); unsigned char * p = (unsigned char *) (wh + 1); int bhlen = 8 + 2 + 2; int len = totlen; char ssid[256]; int wpa = 0; int rc; int ssids = 0; int hidden = 0; struct network * n; totlen -= sizeof(*wh); if (totlen < bhlen) goto __bad; if (!(IEEE80211_BEACON_CAPABILITY(p) & IEEE80211_CAPINFO_PRIVACY)) return; p += bhlen; totlen -= bhlen; ssid[0] = 0; while (totlen > 2) { int id = *p++; int l = *p++; totlen -= 2; if (totlen < l) goto __bad; switch (id) { case IEEE80211_ELEMID_SSID: if (++ssids > 1) break; if (l == 0 || p[0] == 0) hidden = 1; else { memcpy(ssid, p, l); ssid[l] = 0; } break; case IEEE80211_ELEMID_VENDOR: if ((rc = parse_elem_vendor(&p[-2], l + 2)) == -1) goto __bad; if (rc) wpa = 1; break; case IEEE80211_ELEMID_RSN: if ((rc = parse_rsn(p, l, 1)) == -1) goto __bad; if (rc) wpa = 1; break; } p += l; totlen -= l; } if (!wpa) return; n = find_add_net(wh->i_addr3); if (n->n_beaconlen) return; n->n_beaconlen = len; ALLEGE(n->n_beaconlen <= (int) sizeof(n->n_beacon)); memcpy(n->n_beacon, wh, n->n_beaconlen); strncpy(n->n_ssid, ssid, sizeof(n->n_ssid)); (n->n_ssid)[sizeof(n->n_ssid) - 1] = '\0'; check_network(n); return; __bad: printf("bad beacon\n"); }