* Parse a Beacon or ProbeResponse frame and return the * useful information in an ieee80211_scanparams structure. * Status is set to 0 if no problems were found; otherwise * a bitmask of IEEE80211_BPARSE_* items is returned that * describes the problems detected. */
| 482 | * describes the problems detected. |
| 483 | */ |
| 484 | int |
| 485 | ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m, |
| 486 | struct ieee80211_channel *rxchan, struct ieee80211_scanparams *scan) |
| 487 | { |
| 488 | struct ieee80211vap *vap = ni->ni_vap; |
| 489 | struct ieee80211com *ic = ni->ni_ic; |
| 490 | struct ieee80211_frame *wh; |
| 491 | uint8_t *frm, *efrm; |
| 492 | |
| 493 | wh = mtod(m, struct ieee80211_frame *); |
| 494 | frm = (uint8_t *)&wh[1]; |
| 495 | efrm = mtod(m, uint8_t *) + m->m_len; |
| 496 | scan->status = 0; |
| 497 | /* |
| 498 | * beacon/probe response frame format |
| 499 | * |
| 500 | * XXX Update from 802.11-2012 - eg where HT is |
| 501 | * [8] time stamp |
| 502 | * [2] beacon interval |
| 503 | * [2] capability information |
| 504 | * [tlv] ssid |
| 505 | * [tlv] supported rates |
| 506 | * [tlv] country information |
| 507 | * [tlv] channel switch announcement (CSA) |
| 508 | * [tlv] parameter set (FH/DS) |
| 509 | * [tlv] erp information |
| 510 | * [tlv] extended supported rates |
| 511 | * [tlv] WME |
| 512 | * [tlv] WPA or RSN |
| 513 | * [tlv] HT capabilities |
| 514 | * [tlv] HT information |
| 515 | * [tlv] VHT capabilities |
| 516 | * [tlv] VHT information |
| 517 | * [tlv] Atheros capabilities |
| 518 | * [tlv] Mesh ID |
| 519 | * [tlv] Mesh Configuration |
| 520 | */ |
| 521 | IEEE80211_VERIFY_LENGTH(efrm - frm, 12, |
| 522 | return (scan->status = IEEE80211_BPARSE_BADIELEN)); |
| 523 | memset(scan, 0, sizeof(*scan)); |
| 524 | scan->tstamp = frm; frm += 8; |
| 525 | scan->bintval = le16toh(*(uint16_t *)frm); frm += 2; |
| 526 | scan->capinfo = le16toh(*(uint16_t *)frm); frm += 2; |
| 527 | scan->bchan = ieee80211_chan2ieee(ic, rxchan); |
| 528 | scan->chan = scan->bchan; |
| 529 | scan->ies = frm; |
| 530 | scan->ies_len = efrm - frm; |
| 531 | |
| 532 | while (efrm - frm > 1) { |
| 533 | IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, |
| 534 | return (scan->status = IEEE80211_BPARSE_BADIELEN)); |
| 535 | switch (*frm) { |
| 536 | case IEEE80211_ELEMID_SSID: |
| 537 | scan->ssid = frm; |
| 538 | break; |
| 539 | case IEEE80211_ELEMID_RATES: |
| 540 | scan->rates = frm; |
| 541 | break; |
no test coverage detected