/* return length of packet, 0 for bad FCS, -1 on error */ static int parse_radiotap_header(unsigned char** buf, int len, struct packet_info* p) { struct ieee80211_radiotap_header* rh; struct ieee80211_radiotap_iterator iter; int err, rt_len; rh = (struct ieee80211_radiotap_header*)*buf; rt_len = le16toh(rh->it_len); err = ieee80211_radiotap_iterator_init(&iter, rh, rt_len, NULL); if (err) { DEBUG("malformed radiotap header (init returns %d)\n", err); return -1; } DEBUG("Radiotap: "); while (!(err = ieee80211_radiotap_iterator_next(&iter))) { if (iter.is_radiotap_ns) { get_radiotap_info(&iter, p); } } DEBUG("\nSIG %d", p->phy_signal); /* sanitize */ if (p->phy_rate == 0 || p->phy_rate > 6000) { /* assume min rate for mode */ DEBUG("*** fixing wrong rate\n"); if (p->phy_flags & PHY_FLAG_A) p->phy_rate = 120; /* 6 * 2 */ else if (p->phy_flags & PHY_FLAG_B) p->phy_rate = 20; /* 1 * 2 */ else if (p->phy_flags & PHY_FLAG_G) p->phy_rate = 120; /* 6 * 2 */ else p->phy_rate = 20; } DEBUG("\nrate: %.2f = idx %d\n", (float)p->phy_rate/10, p->phy_rate_idx); DEBUG("signal: %d\n", p->phy_signal); if (p->phy_flags & PHY_FLAG_BADFCS) { /* we can't trust frames with a bad FCS - stop parsing */ DEBUG("=== bad FCS, stop ===\n"); return 0; } else { *buf = *buf + rt_len; return len - rt_len; } }
static unsigned char *get_80211(struct priv_fbsd *pf, int *plen, struct rx_info *ri) { struct bpf_hdr *bpfh; struct ieee80211_radiotap_header *rth; void *ptr; unsigned char **data; int *totlen; data = &pf->pf_next; totlen = &pf->pf_totlen; assert(*totlen); /* bpf hdr */ bpfh = (struct bpf_hdr*) (*data); assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */ *totlen -= bpfh->bh_hdrlen; /* check if more packets */ if ((int)bpfh->bh_caplen < *totlen) { int tot = bpfh->bh_hdrlen + bpfh->bh_caplen; int offset = BPF_WORDALIGN(tot); *data = (unsigned char*)bpfh + offset; *totlen -= offset - tot; /* take into account align bytes */ } else if ((int)bpfh->bh_caplen > *totlen) abort(); *plen = bpfh->bh_caplen; *totlen -= bpfh->bh_caplen; assert(*totlen >= 0); /* radiotap */ rth = (struct ieee80211_radiotap_header*) ((char*)bpfh + bpfh->bh_hdrlen); get_radiotap_info(pf, rth, plen, ri); *plen -= rth->it_len; assert(*plen > 0); /* data */ ptr = (char*)rth + rth->it_len; return ptr; }
/* return length of packet, 0 for bad FCS, -1 on error */ static int parse_radiotap_header(unsigned char** buf, int len, struct packet_info* p) { struct ieee80211_radiotap_header* rh; struct ieee80211_radiotap_iterator iter; int err, rt_len; rh = (struct ieee80211_radiotap_header*)*buf; rt_len = le16toh(rh->it_len); err = ieee80211_radiotap_iterator_init(&iter, rh, rt_len, NULL); if (err) { DEBUG("malformed radiotap header (init returns %d)\n", err); return -1; } while (!(err = ieee80211_radiotap_iterator_next(&iter))) { if (iter.is_radiotap_ns) { get_radiotap_info(&iter, p); } } DEBUG("\n"); DEBUG("SIG %d NOI %d SNR %d\n", p->phy_signal, p->phy_noise, p->phy_snr); if (p->phy_signal > 0 || p->phy_signal < -95) p->phy_signal = 0; /* no SNR from radiotap, try to calculate, normal case nowadays */ if (p->phy_snr == 0 && p->phy_signal < 0) { if (p->phy_noise < 0) { p->phy_snr = p->phy_signal - p->phy_noise; } else { /* HACK: here we just assume noise to be -95dBm */ p->phy_snr = p->phy_signal + 95; } } /* sanitize */ if (p->phy_snr > 99) p->phy_snr = 99; if (p->phy_rate == 0 || p->phy_rate > 6000) { /* assume min rate for mode */ DEBUG("*** fixing wrong rate\n"); if (p->phy_flags & PHY_FLAG_A) p->phy_rate = 120; /* 6 * 2 */ else if (p->phy_flags & PHY_FLAG_B) p->phy_rate = 20; /* 1 * 2 */ else if (p->phy_flags & PHY_FLAG_G) p->phy_rate = 120; /* 6 * 2 */ else p->phy_rate = 20; } DEBUG("\nrate: %.2f\n", (float)p->phy_rate/10); DEBUG("rate_idx: %d\n", p->phy_rate_idx); DEBUG("signal: %d\n", p->phy_signal); DEBUG("noise: %d\n", p->phy_noise); DEBUG("snr: %d\n", p->phy_snr); if (p->phy_flags & PHY_FLAG_BADFCS) { /* we can't trust frames with a bad FCS - stop parsing */ DEBUG("=== bad FCS, stop ===\n"); return 0; } else { *buf = *buf + rt_len; return len - rt_len; } }