void ieee80211_notify_replay_failure(struct ieee80211vap *vap, const struct ieee80211_frame *wh, const struct ieee80211_key *k, u_int64_t rsc, int tid) { struct ifnet *ifp = vap->iv_ifp; IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, "%s replay detected tid %d <rsc %ju, csc %ju, keyix %u rxkeyix %u>", k->wk_cipher->ic_name, tid, (intmax_t) rsc, (intmax_t) k->wk_keyrsc[tid], k->wk_keyix, k->wk_rxkeyix); if (ifp != NULL) { /* NB: for cipher test modules */ struct ieee80211_replay_event iev; IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1); IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2); iev.iev_cipher = k->wk_cipher->ic_cipher; if (k->wk_rxkeyix != IEEE80211_KEYIX_NONE) iev.iev_keyix = k->wk_rxkeyix; else iev.iev_keyix = k->wk_keyix; iev.iev_keyrsc = k->wk_keyrsc[tid]; iev.iev_rsc = rsc; CURVNET_SET(ifp->if_vnet); rt_ieee80211msg(ifp, RTM_IEEE80211_REPLAY, &iev, sizeof(iev)); CURVNET_RESTORE(); } }
/* XXX only fetch what's needed to do reports */ static void wlan_collect(struct wlanstatfoo_p *wf, struct ieee80211_stats *stats, struct ieee80211req_sta_stats *nstats) { IEEE80211_ADDR_COPY(wf->u_info.info.is_u.macaddr, wf->mac); wf->ireq.i_type = IEEE80211_IOC_STA_INFO; wf->ireq.i_data = (caddr_t) &wf->u_info; wf->ireq.i_len = sizeof(wf->u_info); if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) { warn("%s:%s (IEEE80211_IOC_STA_INFO)", wf->ireq.i_name, ether_ntoa((const struct ether_addr*) wf->mac)); } IEEE80211_ADDR_COPY(nstats->is_u.macaddr, wf->mac); wf->ireq.i_type = IEEE80211_IOC_STA_STATS; wf->ireq.i_data = (caddr_t) nstats; wf->ireq.i_len = sizeof(*nstats); if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) warn("%s:%s (IEEE80211_IOC_STA_STATS)", wf->ireq.i_name, ether_ntoa((const struct ether_addr*) wf->mac)); wf->ifr.ifr_data = (caddr_t) stats; if (ioctl(wf->s, SIOCG80211STATS, &wf->ifr) < 0) err(1, "%s (SIOCG80211STATS)", wf->ifr.ifr_name); }
void ieee80211_req2node(struct ieee80211com *ic, const struct ieee80211_nodereq *nr, struct ieee80211_node *ni) { /* Node address and name information */ IEEE80211_ADDR_COPY(ni->ni_macaddr, nr->nr_macaddr); IEEE80211_ADDR_COPY(ni->ni_bssid, nr->nr_bssid); ni->ni_esslen = nr->nr_nwid_len; bcopy(nr->nr_nwid, ni->ni_essid, IEEE80211_NWID_LEN); /* Rates */ ni->ni_rates.rs_nrates = nr->nr_nrates; bcopy(nr->nr_rates, ni->ni_rates.rs_rates, IEEE80211_RATE_MAXSIZE); /* Node information */ ni->ni_intval = nr->nr_intval; ni->ni_capinfo = nr->nr_capinfo; ni->ni_fhdwell = nr->nr_fhdwell; ni->ni_fhindex = nr->nr_fhindex; ni->ni_erp = nr->nr_erp; ni->ni_pwrsave = nr->nr_pwrsave; ni->ni_associd = nr->nr_associd; ni->ni_txseq = nr->nr_txseq; ni->ni_rxseq = nr->nr_rxseq; ni->ni_fails = nr->nr_fails; ni->ni_inact = nr->nr_inact; ni->ni_txrate = nr->nr_txrate; ni->ni_state = nr->nr_state; }
/* * Add a Mesh Path Request IE to a frame. */ static uint8_t * hwmp_add_meshpreq(uint8_t *frm, const struct ieee80211_meshpreq_ie *preq) { int i; *frm++ = IEEE80211_ELEMID_MESHPREQ; *frm++ = sizeof(struct ieee80211_meshpreq_ie) - 2 + (preq->preq_tcount - 1) * sizeof(*preq->preq_targets); *frm++ = preq->preq_flags; *frm++ = preq->preq_hopcount; *frm++ = preq->preq_ttl; ADDWORD(frm, preq->preq_id); IEEE80211_ADDR_COPY(frm, preq->preq_origaddr); frm += 6; ADDWORD(frm, preq->preq_origseq); ADDWORD(frm, preq->preq_lifetime); ADDWORD(frm, preq->preq_metric); *frm++ = preq->preq_tcount; for (i = 0; i < preq->preq_tcount; i++) { *frm++ = preq->preq_targets[i].target_flags; IEEE80211_ADDR_COPY(frm, preq->preq_targets[i].target_addr); frm += 6; ADDWORD(frm, preq->preq_targets[i].target_seq); } return frm; }
void ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan) { struct ieee80211_node *ni; struct ifnet *ifp = &ic->ic_if; ni = ic->ic_bss; if (ifp->if_flags & IFF_DEBUG) printf("%s: creating ibss\n", ifp->if_xname); ic->ic_flags |= IEEE80211_F_SIBSS; ni->ni_chan = chan; ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)]; IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr); IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr); if (ic->ic_opmode == IEEE80211_M_IBSS) { if ((ic->ic_flags & IEEE80211_F_DESBSSID) != 0) IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_des_bssid); else ni->ni_bssid[0] |= 0x02; /* local bit for IBSS */ } ni->ni_esslen = ic->ic_des_esslen; memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen); ni->ni_rssi = 0; ni->ni_rstamp = 0; memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp)); ni->ni_intval = ic->ic_lintval; ni->ni_capinfo = IEEE80211_CAPINFO_IBSS; if (ic->ic_flags & IEEE80211_F_WEPON) ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; if (ic->ic_phytype == IEEE80211_T_FH) { ni->ni_fhdwell = 200; /* XXX */ ni->ni_fhindex = 1; } ieee80211_new_state(ic, IEEE80211_S_RUN, -1); }
static void hwmp_rootmode_cb(void *arg) { struct ieee80211vap *vap = (struct ieee80211vap *)arg; struct ieee80211_hwmp_state *hs = vap->iv_hwmp; struct ieee80211_mesh_state *ms = vap->iv_mesh; struct ieee80211_meshpreq_ie preq; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, "%s", "send broadcast PREQ"); preq.preq_flags = IEEE80211_MESHPREQ_FLAGS_AM; if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PR; if (hs->hs_rootmode == IEEE80211_HWMP_ROOTMODE_PROACTIVE) preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PP; preq.preq_hopcount = 0; preq.preq_ttl = ms->ms_ttl; preq.preq_id = ++hs->hs_preqid; IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); preq.preq_origseq = ++hs->hs_seq; preq.preq_lifetime = ticks_to_msecs(ieee80211_hwmp_roottimeout); preq.preq_metric = IEEE80211_MESHLMETRIC_INITIALVAL; preq.preq_tcount = 1; IEEE80211_ADDR_COPY(PREQ_TADDR(0), broadcastaddr); PREQ_TFLAGS(0) = IEEE80211_MESHPREQ_TFLAGS_TO | IEEE80211_MESHPREQ_TFLAGS_RF; PREQ_TSEQ(0) = 0; vap->iv_stats.is_hwmp_rootreqs++; hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq); hwmp_rootmode_setup(vap); }
int ieee80211_wep_mbssid_mac(struct ieee80211vap *vap, const struct ieee80211_key *k, u_int8_t *gmac) { if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) { if (k->wk_flags & IEEE80211_KEY_RECV) { /* * This is for the WEP tx key by "iwconfig" or WEP rx key that is installed * by crypto_installkey(). */ IEEE80211_ADDR_COPY(gmac, vap->iv_myaddr); } else { /* * For _M_STA, set the multicast key that is installed by * crypto_install_mcastkey() for decypting the received * multicast frames from root AP. */ IEEE80211_ADDR_COPY(gmac, vap->iv_bss->ni_macaddr); gmac[0] |= 0x01; } return 1; } else { /* * If not WEP mode, no changes. */ return 0; } }
int an_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) { struct an_softc *sc = ic->ic_softc; struct ieee80211_node *ni = ic->ic_bss; enum ieee80211_state ostate; int buflen; ostate = ic->ic_state; DPRINTF(("an_newstate: %s -> %s\n", ieee80211_state_name[ostate], ieee80211_state_name[nstate])); switch (nstate) { case IEEE80211_S_INIT: ic->ic_flags &= ~IEEE80211_F_IBSSON; return (*sc->sc_newstate)(ic, nstate, arg); case IEEE80211_S_RUN: buflen = sizeof(sc->sc_buf); an_read_rid(sc, AN_RID_STATUS, &sc->sc_buf, &buflen); an_swap16((u_int16_t *)&sc->sc_buf.sc_status.an_cur_bssid, 3); an_swap16((u_int16_t *)&sc->sc_buf.sc_status.an_ssid, 16); IEEE80211_ADDR_COPY(ni->ni_bssid, sc->sc_buf.sc_status.an_cur_bssid); IEEE80211_ADDR_COPY(ni->ni_macaddr, ni->ni_bssid); ni->ni_chan = &ic->ic_channels[ sc->sc_buf.sc_status.an_cur_channel]; ni->ni_esslen = sc->sc_buf.sc_status.an_ssidlen; if (ni->ni_esslen > IEEE80211_NWID_LEN) ni->ni_esslen = IEEE80211_NWID_LEN; /*XXX*/ memcpy(ni->ni_essid, sc->sc_buf.sc_status.an_ssid, ni->ni_esslen); ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B]; /*XXX*/ if (ic->ic_if.if_flags & IFF_DEBUG) { printf("%s: ", sc->sc_dev.dv_xname); if (ic->ic_opmode == IEEE80211_M_STA) printf("associated "); else printf("synchronized "); printf("with %s ssid ", ether_sprintf(ni->ni_bssid)); ieee80211_print_essid(ni->ni_essid, ni->ni_esslen); printf(" channel %u start %uMb\n", sc->sc_buf.sc_status.an_cur_channel, sc->sc_buf.sc_status.an_current_tx_rate/2); } break; default: break; } ic->ic_state = nstate; /* skip standard ieee80211 handling */ return 0; }
/** * @brief Routine to accept station statistics request * * @param vap * @param ni * @param req * @param rm_token * * @return * @return on success return 0. * on failure returns -ve value. */ int ieee80211_rrm_recv_stastats_req(wlan_if_t vap, wlan_node_t ni, struct ieee80211_measreq_ie *req,u_int8_t rm_token) { struct ieee80211_rrmreq_info *params; struct ieee80211_stastatsreq *statsreq; RRM_FUNCTION_ENTER; statsreq = (struct ieee80211_stastatsreq *)(&(req->req[0])); params = (struct ieee80211_rrmreq_info *) OS_MALLOC(vap->rrm->rrm_osdev, sizeof(struct ieee80211_rrmreq_info), 0); if(NULL == params) return -EBUSY; params->rm_dialogtoken = rm_token; params->rep_dialogtoken= req->token; params->duration=statsreq->mduration; params->gid=statsreq->gid; RRM_DEBUG(vap, RRM_DEBUG_INFO, "%s : duration %d chnum %d gid %d\n", __func__, params->duration, params->chnum, params->gid); IEEE80211_ADDR_COPY(params->bssid,statsreq->dstmac); ieee80211_rrm_set_report_pending(vap,IEEE80211_MEASREQ_STA_STATS_REQ,(void *)params); if(vap->rrm->pending_report) ieee80211_send_report(vap->rrm); RRM_FUNCTION_EXIT; return EOK; }
void ieee80211_setup_node(struct ieee80211com *ic, struct ieee80211_node *ni, const u_int8_t *macaddr) { int s; DPRINTF(("%s\n", ether_sprintf((u_int8_t *)macaddr))); IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); ieee80211_node_newstate(ni, IEEE80211_STA_CACHE); ni->ni_ic = ic; /* back-pointer */ #ifndef IEEE80211_STA_ONLY IFQ_SET_MAXLEN(&ni->ni_savedq, IEEE80211_PS_MAX_QUEUE); timeout_set(&ni->ni_eapol_to, ieee80211_eapol_timeout, ni); timeout_set(&ni->ni_sa_query_to, ieee80211_sa_query_timeout, ni); #endif /* * Note we don't enable the inactive timer when acting * as a station. Nodes created in this mode represent * AP's identified while scanning. If we time them out * then several things happen: we can't return the data * to users to show the list of AP's we encountered, and * more importantly, we'll incorrectly deauthenticate * ourself because the inactivity timer will kick us off. */ s = splnet(); if (ic->ic_opmode != IEEE80211_M_STA && RB_EMPTY(&ic->ic_tree)) ic->ic_inact_timer = IEEE80211_INACT_WAIT; RB_INSERT(ieee80211_tree, &ic->ic_tree, ni); splx(s); }
/* * Drivers call this, so increase the reference count before returning * the node. */ struct ieee80211_node * Voodoo80211Device:: ieee80211_find_rxnode(struct ieee80211com *ic, const struct ieee80211_frame *wh) { static const u_int8_t zero[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; struct ieee80211_node *ni; const u_int8_t *bssid; int s; if (!ieee80211_needs_rxnode(ic, wh, &bssid)) return ieee80211_ref_node(ic->ic_bss); s = splnet(); ni = ieee80211_find_node(ic, wh->i_addr2); splx(s); if (ni != NULL) return ieee80211_ref_node(ni); /* XXX see remarks in ieee80211_find_txnode */ /* XXX no rate negotiation; just dup */ if ((ni = ieee80211_dup_bss(ic, wh->i_addr2)) == NULL) return ieee80211_ref_node(ic->ic_bss); IEEE80211_ADDR_COPY(ni->ni_bssid, (bssid != NULL) ? bssid : zero); ni->ni_rates = ic->ic_bss->ni_rates; ieee80211_newassoc(ic, ni, 1); DPRINTF(("faked-up node %p for %s\n", ni, ether_sprintf((u_int8_t *)wh->i_addr2))); return ieee80211_ref_node(ni); }
/* * Drivers call this, so increase the reference count before returning * the node. */ struct ieee80211_node * ieee80211_find_rxnode(struct ieee80211com *ic, struct ieee80211_frame *wh) { struct ieee80211_node *ni; const static u_int8_t zero[IEEE80211_ADDR_LEN]; u_int8_t *bssid; if (!ieee80211_needs_rxnode(ic, wh, &bssid)) return ieee80211_ref_node(ic->ic_bss); IEEE80211_NODE_LOCK(ic); ni = ieee80211_find_node(ic, wh->i_addr2); IEEE80211_NODE_UNLOCK(ic); if (ni != NULL) return ieee80211_ref_node(ni); if (ic->ic_opmode == IEEE80211_M_HOSTAP) return ieee80211_ref_node(ic->ic_bss); /* XXX see remarks in ieee80211_find_txnode */ /* XXX no rate negotiation; just dup */ if ((ni = ieee80211_dup_bss(ic, wh->i_addr2)) == NULL) return ieee80211_ref_node(ic->ic_bss); IEEE80211_ADDR_COPY(ni->ni_bssid, (bssid != NULL) ? bssid : zero); ni->ni_rates = ic->ic_bss->ni_rates; if (ic->ic_newassoc) (*ic->ic_newassoc)(ic, ni, 1); IEEE80211_DPRINTF(("%s: faked-up node %p for %s\n", __func__, ni, ether_sprintf(wh->i_addr2))); return ieee80211_ref_node(ni); }
static int wds_vap_create(const char *parent, struct wds *p) { struct ieee80211_clone_params cp; struct ifreq ifr; int s, status; memset(&cp, 0, sizeof(cp)); strncpy(cp.icp_parent, parent, IFNAMSIZ); cp.icp_opmode = IEEE80211_M_WDS; IEEE80211_ADDR_COPY(cp.icp_bssid, p->bssid); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, "wlan", IFNAMSIZ); ifr.ifr_data = (void *) &cp; status = -1; s = socket(AF_INET, SOCK_DGRAM, 0); if (s >= 0) { if (ioctl(s, SIOCIFCREATE2, &ifr) >= 0) { strlcpy(p->ifname, ifr.ifr_name, IFNAMSIZ); status = 0; } else { syslog(LOG_ERR, "SIOCIFCREATE2(" "mode %u flags 0x%x parent %s bssid %s): %m", cp.icp_opmode, cp.icp_flags, parent, ether_sprintf(cp.icp_bssid)); } close(s); } else syslog(LOG_ERR, "socket(SOCK_DRAGM): %m"); return status; }
void r21a_parse_rom(struct rtwn_softc *sc, uint8_t *buf) { struct r12a_softc *rs = sc->sc_priv; struct r12a_rom *rom = (struct r12a_rom *)buf; uint8_t pa_type, lna_type_2g, lna_type_5g; /* Read PA/LNA types. */ pa_type = RTWN_GET_ROM_VAR(rom->pa_type, 0); lna_type_2g = RTWN_GET_ROM_VAR(rom->lna_type_2g, 0); lna_type_5g = RTWN_GET_ROM_VAR(rom->lna_type_5g, 0); rs->ext_pa_2g = R21A_ROM_IS_PA_EXT_2GHZ(pa_type); rs->ext_pa_5g = R21A_ROM_IS_PA_EXT_5GHZ(pa_type); rs->ext_lna_2g = R21A_ROM_IS_LNA_EXT(lna_type_2g); rs->ext_lna_5g = R21A_ROM_IS_LNA_EXT(lna_type_5g); RTWN_LOCK(sc); rs->bt_coex = !!(rtwn_read_4(sc, R92C_MULTI_FUNC_CTRL) & R92C_MULTI_BT_FUNC_EN); RTWN_UNLOCK(sc); rs->bt_ant_num = (rom->rf_bt_opt & R12A_RF_BT_OPT_ANT_NUM); /* Read MAC address. */ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr_21a); /* Execute common part of initialization. */ r12a_parse_rom_common(sc, buf); }
/* * Send a Root Annoucement (RANN) to find all the nodes on the mesh. We are * called when the vap is configured as a HWMP RANN root node. */ static void hwmp_rootmode_rann_callout(void *arg) { struct ieee80211vap *vap = (struct ieee80211vap *)arg; struct ieee80211_hwmp_state *hs; struct ieee80211_mesh_state *ms; struct ieee80211_meshrann_ie rann; wlan_serialize_enter(); hs = vap->iv_hwmp; ms = vap->iv_mesh; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, "%s", "send broadcast RANN"); rann.rann_flags = 0; if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) rann.rann_flags |= IEEE80211_MESHRANN_FLAGS_PR; rann.rann_hopcount = 0; rann.rann_ttl = ms->ms_ttl; IEEE80211_ADDR_COPY(rann.rann_addr, vap->iv_myaddr); rann.rann_seq = ++hs->hs_seq; rann.rann_metric = IEEE80211_MESHLMETRIC_INITIALVAL; vap->iv_stats.is_hwmp_rootrann++; hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &rann); hwmp_rootmode_setup(vap); wlan_serialize_exit(); }
/* * Create a HOSTAP node on current channel based on ssid. */ int ieee80211_create_infra_bss(struct ieee80211vap *vap, const u_int8_t *essid, const u_int16_t esslen) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni; ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr); if (ni == NULL) return -ENOMEM; IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr); ni->ni_esslen = esslen; OS_MEMCPY(ni->ni_essid, essid, ni->ni_esslen); ni->ni_intval = ic->ic_intval; if (IEEE80211_VAP_IS_PRIVACY_ENABLED(vap)) { ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; ni->ni_rsn = vap->iv_rsn; /* use local RSN settings as the BSS setting */ } /* Set the node htcap to be same as ic htcap */ ni->ni_htcap = ic->ic_htcap; IEEE80211_ADD_NODE_TARGET(ni, ni->ni_vap, 1); /* copy the original bssinfo into the new ni BugID: Ev# 73905 */ ieee80211_copy_bss(ni, vap->iv_bss); return ieee80211_sta_join_bss(ni); }
/* * Add a Mesh Path Reply IE to a frame. */ static uint8_t * hwmp_add_meshprep(uint8_t *frm, const struct ieee80211_meshprep_ie *prep) { *frm++ = IEEE80211_ELEMID_MESHPREP; *frm++ = sizeof(struct ieee80211_meshprep_ie) - 2; *frm++ = prep->prep_flags; *frm++ = prep->prep_hopcount; *frm++ = prep->prep_ttl; IEEE80211_ADDR_COPY(frm, prep->prep_targetaddr); frm += 6; ADDWORD(frm, prep->prep_targetseq); ADDWORD(frm, prep->prep_lifetime); ADDWORD(frm, prep->prep_metric); IEEE80211_ADDR_COPY(frm, prep->prep_origaddr); frm += 6; ADDWORD(frm, prep->prep_origseq); return frm; }
static void hwmp_peerdown(struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_mesh_state *ms = vap->iv_mesh; struct ieee80211_meshperr_ie perr; struct ieee80211_mesh_route *rt; struct ieee80211_hwmp_route *hr; rt = ieee80211_mesh_rt_find(vap, ni->ni_macaddr); if (rt == NULL) return; hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "%s", "delete route entry"); perr.perr_ttl = ms->ms_ttl; perr.perr_ndests = 1; PERR_DFLAGS(0) = 0; if (hr->hr_seq == 0) PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN; PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC; IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest); PERR_DSEQ(0) = hr->hr_seq; PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH; /* NB: flush everything passing through peer */ ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr); hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr); }
/* * Return "hw specs". Note this must be the first cmd MUST be done after * a firmware download or the f/w will lockup. */ int malo_hal_gethwspecs(struct malo_hal *mh, struct malo_hal_hwspec *hw) { struct malo_cmd_get_hwspec *cmd; int ret; MALO_HAL_LOCK(mh); _CMD_SETUP(cmd, struct malo_cmd_get_hwspec, MALO_HOSTCMD_GET_HW_SPEC); memset(&cmd->permaddr[0], 0xff, IEEE80211_ADDR_LEN); cmd->ul_fw_awakecookie = htole32((unsigned int)mh->mh_cmdaddr + 2048); ret = malo_hal_execute_cmd(mh, MALO_HOSTCMD_GET_HW_SPEC); if (ret == 0) { IEEE80211_ADDR_COPY(hw->macaddr, cmd->permaddr); hw->wcbbase[0] = le32toh(cmd->wcbbase0) & 0x0000ffff; hw->wcbbase[1] = le32toh(cmd->wcbbase1) & 0x0000ffff; hw->wcbbase[2] = le32toh(cmd->wcbbase2) & 0x0000ffff; hw->wcbbase[3] = le32toh(cmd->wcbbase3) & 0x0000ffff; hw->rxdesc_read = le32toh(cmd->rxpdrd_ptr)& 0x0000ffff; hw->rxdesc_write = le32toh(cmd->rxpdwr_ptr)& 0x0000ffff; hw->regioncode = le16toh(cmd->regioncode) & 0x00ff; hw->fw_releasenum = le32toh(cmd->fw_releasenum); hw->maxnum_wcb = le16toh(cmd->num_wcb); hw->maxnum_mcaddr = le16toh(cmd->num_mcastaddr); hw->num_antenna = le16toh(cmd->num_antenna); hw->hwversion = cmd->version; hw->hostinterface = cmd->hostif; } MALO_HAL_UNLOCK(mh); return ret; }
static void wlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac) { static const uint8_t zeromac[IEEE80211_ADDR_LEN]; struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; if (mac == NULL) { switch (wlan_getopmode(wf0)) { case IEEE80211_M_HOSTAP: case IEEE80211_M_MONITOR: getlladdr(wf); break; case IEEE80211_M_IBSS: case IEEE80211_M_AHDEMO: /* * NB: this may not work in which case the * mac must be specified on the command line */ if (getbssid(wf) < 0 || IEEE80211_ADDR_EQ(wf->mac, zeromac)) getlladdr(wf); break; case IEEE80211_M_STA: if (getbssid(wf) < 0) err(1, "%s (IEEE80211_IOC_BSSID)", wf->ireq.i_name); break; } } else IEEE80211_ADDR_COPY(wf->mac, mac); }
int wlan_reset(wlan_if_t vaphandle, ieee80211_reset_request *reset_req) { struct ieee80211vap *vap = vaphandle; struct ieee80211com *ic = vap->iv_ic; int err = 0; /* NB: must set H/W MAC address before chip reset */ if (reset_req->reset_mac && IEEE80211_ADDR_IS_VALID(reset_req->macaddr) && !IEEE80211_ADDR_EQ(reset_req->macaddr, ic->ic_myaddr)) { IEEE80211_ADDR_COPY(ic->ic_myaddr, reset_req->macaddr); ic->ic_set_macaddr(ic, reset_req->macaddr); IEEE80211_ADDR_COPY(vap->iv_myaddr, ic->ic_myaddr); /* * TBD: if OS tries to set mac addr when multiple VAP co-exist, * we need to notify other VAPs and the corresponding ports * so that the port owner can change source address!! */ } /* reset UMAC software states */ if (reset_req->type == IEEE80211_RESET_TYPE_DOT11_INTF) { /* * In case iv_bss was not stopped. */ wlan_mlme_stop_bss(vap, WLAN_MLME_STOP_BSS_F_FORCE_STOP_RESET | WLAN_MLME_STOP_BSS_F_WAIT_RX_DONE); err = ieee80211_vap_reset(vap, reset_req); } else if (reset_req->type == IEEE80211_RESET_TYPE_DEVICE) { u_int32_t num_vaps; struct ieee80211_vap_iter_reset_arg params; params.err=0; params.reset_req = reset_req; ieee80211_iterate_vap_list_internal(ic,ieee80211_vap_iter_reset,((void *) ¶ms),num_vaps); err = params.err; } /* TBD: Always reset the hardware? */ err = ic->ic_reset(ic); if (err) return err; return err; }
struct ieee80211_node * ieee80211_find_node(struct ieee80211com *ic, u_int8_t *macaddr) { struct ieee80211_node ni; IEEE80211_ADDR_COPY(ni.ni_macaddr, macaddr); return (RB_FIND(ieee80211_tree, &ic->ic_tree, &ni)); }
void r92c_parse_rom(struct rtwn_softc *sc, uint8_t *buf) { struct r92c_softc *rs = sc->sc_priv; struct rtwn_r92c_txpwr *rt = rs->rs_txpwr; struct r92c_rom *rom = (struct r92c_rom *)buf; int i, j; rs->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE); rs->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY); RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: regulatory type=%d\n", __func__, rs->regulatory); /* Need to be set before postinit() (but after preinit()). */ rtwn_r92c_set_rom_opts(sc, buf); r92c_set_chains(sc); for (j = 0; j < R92C_GROUP_2G; j++) { for (i = 0; i < sc->ntxchains; i++) { rt->cck_tx_pwr[i][j] = rom->cck_tx_pwr[i][j]; rt->ht40_1s_tx_pwr[i][j] = rom->ht40_1s_tx_pwr[i][j]; } rt->ht40_2s_tx_pwr_diff[0][j] = MS(rom->ht40_2s_tx_pwr_diff[j], LOW_PART); rt->ht20_tx_pwr_diff[0][j] = RTWN_SIGN4TO8(MS(rom->ht20_tx_pwr_diff[j], LOW_PART)); rt->ofdm_tx_pwr_diff[0][j] = MS(rom->ofdm_tx_pwr_diff[j], LOW_PART); rt->ht40_max_pwr[0][j] = MS(rom->ht40_max_pwr[j], LOW_PART); rt->ht20_max_pwr[0][j] = MS(rom->ht20_max_pwr[j], LOW_PART); if (sc->ntxchains > 1) { rt->ht40_2s_tx_pwr_diff[1][j] = MS(rom->ht40_2s_tx_pwr_diff[j], HIGH_PART); rt->ht20_tx_pwr_diff[1][j] = RTWN_SIGN4TO8(MS(rom->ht20_tx_pwr_diff[j], HIGH_PART)); rt->ofdm_tx_pwr_diff[1][j] = MS(rom->ofdm_tx_pwr_diff[j], HIGH_PART); rt->ht40_max_pwr[1][j] = MS(rom->ht40_max_pwr[j], HIGH_PART); rt->ht20_max_pwr[1][j] = MS(rom->ht20_max_pwr[j], HIGH_PART); } } sc->thermal_meter = MS(rom->thermal_meter, R92C_ROM_THERMAL_METER); if (sc->thermal_meter == R92C_ROM_THERMAL_METER_M) sc->thermal_meter = 0xff; IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr); }
void ieee80211_node2req(struct ieee80211com *ic, const struct ieee80211_node *ni, struct ieee80211_nodereq *nr) { /* Node address and name information */ IEEE80211_ADDR_COPY(nr->nr_macaddr, ni->ni_macaddr); IEEE80211_ADDR_COPY(nr->nr_bssid, ni->ni_bssid); nr->nr_nwid_len = ni->ni_esslen; bcopy(ni->ni_essid, nr->nr_nwid, IEEE80211_NWID_LEN); /* Channel and rates */ nr->nr_channel = ieee80211_chan2ieee(ic, ni->ni_chan); nr->nr_chan_flags = ni->ni_chan->ic_flags; nr->nr_nrates = ni->ni_rates.rs_nrates; bcopy(ni->ni_rates.rs_rates, nr->nr_rates, IEEE80211_RATE_MAXSIZE); /* Node status information */ nr->nr_rssi = (*ic->ic_node_getrssi)(ic, ni); nr->nr_max_rssi = ic->ic_max_rssi; bcopy(ni->ni_tstamp, nr->nr_tstamp, sizeof(nr->nr_tstamp)); nr->nr_intval = ni->ni_intval; nr->nr_capinfo = ni->ni_capinfo; nr->nr_fhdwell = ni->ni_fhdwell; nr->nr_fhindex = ni->ni_fhindex; nr->nr_erp = ni->ni_erp; nr->nr_pwrsave = ni->ni_pwrsave; nr->nr_associd = ni->ni_associd; nr->nr_txseq = ni->ni_txseq; nr->nr_rxseq = ni->ni_rxseq; nr->nr_fails = ni->ni_fails; nr->nr_inact = ni->ni_inact; nr->nr_txrate = ni->ni_txrate; nr->nr_state = ni->ni_state; /* XXX RSN */ /* Node flags */ nr->nr_flags = 0; if (bcmp(nr->nr_macaddr, nr->nr_bssid, IEEE80211_ADDR_LEN) == 0) nr->nr_flags |= IEEE80211_NODEREQ_AP; if (ni == ic->ic_bss) nr->nr_flags |= IEEE80211_NODEREQ_AP_BSS; }
/* * Helper function for events that pass just a single mac address. */ static void notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211_join_event iev; CURVNET_SET(ifp->if_vnet); memset(&iev, 0, sizeof(iev)); IEEE80211_ADDR_COPY(iev.iev_addr, mac); rt_ieee80211msg(ifp, op, &iev, sizeof(iev)); CURVNET_RESTORE(); }
/* * Fill in probe request with the following parameters: * TA is our vif HW address, which mac80211 ensures we have. * Packet is broadcasted, so this is both SA and DA. * The probe request IE is made out of two: first comes the most prioritized * SSID if a directed scan is requested. Second comes whatever extra * information was given to us as the scan request IE. */ static uint16_t iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct ieee80211_frame *frame, const uint8_t *ta, int n_ssids, const uint8_t *ssid, int ssid_len, const uint8_t *ie, int ie_len, int left) { uint8_t *pos = NULL; /* Make sure there is enough space for the probe request, * two mandatory IEs and the data */ left -= sizeof(*frame); if (left < 0) return 0; frame->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ; frame->i_fc[1] = IEEE80211_FC1_DIR_NODS; IEEE80211_ADDR_COPY(frame->i_addr1, ieee80211broadcastaddr); IEEE80211_ADDR_COPY(frame->i_addr2, ta); IEEE80211_ADDR_COPY(frame->i_addr3, ieee80211broadcastaddr); /* for passive scans, no need to fill anything */ if (n_ssids == 0) return sizeof(*frame); /* points to the payload of the request */ pos = (uint8_t *)frame + sizeof(*frame); /* fill in our SSID IE */ left -= ssid_len + 2; if (left < 0) return 0; pos = ieee80211_add_ssid(pos, ssid, ssid_len); if (ie && ie_len && left >= ie_len) { memcpy(pos, ie, ie_len); pos += ie_len; } return pos - (uint8_t *)frame; }
int wlan_vap_get_bssid(wlan_if_t vaphandle, u_int8_t *bssid) { /* need locking to prevent changing the iv_bss */ IEEE80211_VAP_LOCK(vaphandle); if (vaphandle->iv_bss) { IEEE80211_ADDR_COPY(bssid, vaphandle->iv_bss->ni_bssid); IEEE80211_VAP_UNLOCK(vaphandle); return EOK; } IEEE80211_VAP_UNLOCK(vaphandle); return -EINVAL; }
/** * @brief * * @param vap * @param ni * @param req * @param rm_token * * @return * @return on success return 0. * on failure returns -ve value. */ int ieee80211_rrm_recv_beacon_req(wlan_if_t vap, wlan_node_t ni, struct ieee80211_measreq_ie *req,u_int8_t rm_token) { struct ieee80211_rrmreq_info *params=NULL; struct ieee80211_beaconreq *bcnreq=NULL; RRM_FUNCTION_ENTER; bcnreq = (struct ieee80211_beaconreq *)(&(req->req[0])); params = (struct ieee80211_rrmreq_info *) OS_MALLOC(vap->rrm->rrm_osdev, sizeof(struct ieee80211_rrmreq_info), 0); if(NULL == params) return -EBUSY; params->rm_dialogtoken = rm_token; params->rep_dialogtoken= req->token; params->duration=bcnreq->duration; params->chnum = bcnreq->channum; RRM_DEBUG(vap, RRM_DEBUG_INFO, "%s : duration %d chnum %d regclass %d\n", __func__, params->duration, params->chnum, params->regclass); IEEE80211_ADDR_COPY(params->bssid,bcnreq->bssid); ieee80211_rrm_set_report_pending(vap,IEEE80211_MEASREQ_BR_TYPE,(void *)params); if(vap->rrm->rrm_last_scan == 0) { ieee80211_rrm_scan(vap, bcnreq->mode); return EOK; } else { u_int32_t last_scan_time=0,msec_current_time = 0; last_scan_time = (u_int32_t) CONVERT_SYSTEM_TIME_TO_MS(vap->rrm->rrm_last_scan); msec_current_time = (u_int32_t) CONVERT_SYSTEM_TIME_TO_MS(OS_GET_TIMESTAMP()); msec_current_time -= last_scan_time; if(msec_current_time < 60*1000) { if(vap->rrm->pending_report) ieee80211_send_report(vap->rrm); } else { ieee80211_rrm_scan(vap, bcnreq->mode); } } RRM_FUNCTION_EXIT; return EOK; }
/* * Add a Root Annoucement IE to a frame. */ static uint8_t * hwmp_add_meshrann(uint8_t *frm, const struct ieee80211_meshrann_ie *rann) { *frm++ = IEEE80211_ELEMID_MESHRANN; *frm++ = sizeof(struct ieee80211_meshrann_ie) - 2; *frm++ = rann->rann_flags; *frm++ = rann->rann_hopcount; *frm++ = rann->rann_ttl; IEEE80211_ADDR_COPY(frm, rann->rann_addr); frm += 6; ADDWORD(frm, rann->rann_seq); ADDWORD(frm, rann->rann_metric); return frm; }
void ieee80211_notify_michael_failure(struct ieee80211vap *vap, const struct ieee80211_frame *wh, u_int keyix) { struct ifnet *ifp = vap->iv_ifp; IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, "michael MIC verification failed <keyix %u>", keyix); vap->iv_stats.is_rx_tkipmic++; if (ifp != NULL) { /* NB: for cipher test modules */ struct ieee80211_michael_event iev; IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1); IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2); iev.iev_cipher = IEEE80211_CIPHER_TKIP; iev.iev_keyix = keyix; CURVNET_SET(ifp->if_vnet); rt_ieee80211msg(ifp, RTM_IEEE80211_MICHAEL, &iev, sizeof(iev)); CURVNET_RESTORE(); } }