tx80211_MgmtMsg_t *mlmeApiPrepMgtMsg(UINT32 Subtype, IEEEtypes_MacAddr_t *DestAddr, IEEEtypes_MacAddr_t *SrcAddr) #endif { macmgmtQ_MgmtMsg2_t * MgmtMsg_p; //tx80211_MgmtMsg_t * TxMsg_p; //UINT32 size; #ifdef AP_MAC_LINUX struct sk_buff *skb; UINT8 *frm; if ((skb = ieee80211_getmgtframe(&frm, sizeof(struct ieee80211_frame)+2)) != NULL) { //skb->len = 34; //skb->tail+= 34; WLDBG_INFO(DBG_LEVEL_8, "mlmeApiPrepMgtMsg length = %d \n", skb->len); MgmtMsg_p = (macmgmtQ_MgmtMsg2_t *) skb->data; MgmtMsg_p->Hdr.FrmCtl.Type = IEEE_TYPE_MANAGEMENT; MgmtMsg_p->Hdr.FrmCtl.Subtype = Subtype; MgmtMsg_p->Hdr.FrmCtl.Retry=0; MgmtMsg_p->Hdr.Duration = 300; memcpy(&MgmtMsg_p->Hdr.DestAddr, DestAddr, sizeof(IEEEtypes_MacAddr_t)); memcpy(&MgmtMsg_p->Hdr.SrcAddr, SrcAddr, sizeof(IEEEtypes_MacAddr_t)); memcpy(&MgmtMsg_p->Hdr.BssId, SrcAddr, sizeof(IEEEtypes_MacAddr_t)); } return skb; #else #ifdef AP_BUFFER if ((TxMsg_p = (tx80211_MgmtMsg_t *)pool_GetBuf(txMgmtPoolId)) != NULL) { MgmtMsg_p = &TxMsg_p->MgmtFrame; MgmtMsg_p->Hdr.FrmCtl.Type = IEEE_TYPE_MANAGEMENT; MgmtMsg_p->Hdr.FrmCtl.Subtype = Subtype; MgmtMsg_p->Hdr.FrmCtl.Retry=0; MgmtMsg_p->Hdr.Duration = 300; memcpy(&MgmtMsg_p->Hdr.DestAddr, DestAddr, sizeof(IEEEtypes_MacAddr_t)); memcpy(&MgmtMsg_p->Hdr.SrcAddr, SrcAddr, sizeof(IEEEtypes_MacAddr_t)); memcpy(&MgmtMsg_p->Hdr.BssId, SrcAddr, sizeof(IEEEtypes_MacAddr_t)); } return TxMsg_p; #else return NULL; #endif #endif }
static int hwmp_send_action(struct ieee80211_node *ni, const uint8_t sa[IEEE80211_ADDR_LEN], const uint8_t da[IEEE80211_ADDR_LEN], uint8_t *ie, size_t len) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct ieee80211_bpf_params params; struct mbuf *m; uint8_t *frm; #ifdef IEEE80211_DEBUG_REFCNT char ethstr[ETHER_ADDRSTRLEN + 1]; #endif if (vap->iv_state == IEEE80211_S_CAC) { IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni, "block %s frame in CAC state", "HWMP action"); vap->iv_stats.is_tx_badstate++; return EIO; /* XXX */ } KASSERT(ni != NULL, ("null node")); /* * Hold a reference on the node so it doesn't go away until after * the xmit is complete all the way in the driver. On error we * will remove our reference. */ #ifdef IEEE80211_DEBUG_REFCNT IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, ni, kether_ntoa(ni->ni_macaddr, ethstr), ieee80211_node_refcnt(ni)+1); #endif ieee80211_ref_node(ni); m = ieee80211_getmgtframe(&frm, ic->ic_headroom + sizeof(struct ieee80211_frame), sizeof(struct ieee80211_action) + len ); if (m == NULL) { ieee80211_free_node(ni); vap->iv_stats.is_tx_nobuf++; return ENOMEM; } *frm++ = IEEE80211_ACTION_CAT_MESHPATH; *frm++ = IEEE80211_ACTION_MESHPATH_SEL; switch (*ie) { case IEEE80211_ELEMID_MESHPREQ: frm = hwmp_add_meshpreq(frm, (struct ieee80211_meshpreq_ie *)ie); break; case IEEE80211_ELEMID_MESHPREP: frm = hwmp_add_meshprep(frm, (struct ieee80211_meshprep_ie *)ie); break; case IEEE80211_ELEMID_MESHPERR: frm = hwmp_add_meshperr(frm, (struct ieee80211_meshperr_ie *)ie); break; case IEEE80211_ELEMID_MESHRANN: frm = hwmp_add_meshrann(frm, (struct ieee80211_meshrann_ie *)ie); break; } m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); M_PREPEND(m, sizeof(struct ieee80211_frame), MB_DONTWAIT); if (m == NULL) { ieee80211_free_node(ni); vap->iv_stats.is_tx_nobuf++; return ENOMEM; } ieee80211_send_setup(ni, m, IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION, IEEE80211_NONQOS_TID, sa, da, sa); m->m_flags |= M_ENCAP; /* mark encapsulated */ IEEE80211_NODE_STAT(ni, tx_mgmt); memset(¶ms, 0, sizeof(params)); params.ibp_pri = WME_AC_VO; params.ibp_rate0 = ni->ni_txparms->mgmtrate; if (IEEE80211_IS_MULTICAST(da)) params.ibp_try0 = 1; else params.ibp_try0 = ni->ni_txparms->maxretry; params.ibp_power = ni->ni_txpower; return ic->ic_raw_xmit(ni, m, ¶ms); }
void ieee80211_send_report(ieee80211_rrm_t rrm) { struct ieee80211vap *vap =NULL; struct ieee80211_node *ni = NULL; struct ieee80211_measrsp_ie *measrsp=NULL; wbuf_t wbuf = NULL; u_int8_t *frm = NULL,*fptr = NULL; struct ieee80211_action_rm_rsp *rm_rsp=NULL; struct ieee80211_rrmreq_info *params=NULL; enum ieee80211_opmode opmode; params = (struct ieee80211_rrmreq_info *)(rrm->rrmcb); vap = rrm->rrm_vap; opmode = wlan_vap_get_opmode(vap); ni = rrm->ni; RRM_FUNCTION_ENTER; wbuf = ieee80211_getmgtframe(ni,IEEE80211_FC0_SUBTYPE_ACTION, &frm,0); if(wbuf == NULL) return; rm_rsp = (struct ieee80211_action_rm_rsp *)(frm); rm_rsp->header.ia_category = IEEE80211_ACTION_CAT_RM; rm_rsp->header.ia_action = IEEE80211_ACTION_RM_RESP; rm_rsp->dialogtoken = params->rm_dialogtoken; switch(rrm->pending_report_type) { case IEEE80211_MEASREQ_BR_TYPE: fptr = ieee80211_rrm_send_bcnreq_resp(rrm,&rm_rsp->rsp_ies[0]); break; case IEEE80211_MEASREQ_CHANNEL_LOAD_REQ: fptr = ieee80211_rrm_send_chload_resp(rrm,&rm_rsp->rsp_ies[0]); break; case IEEE80211_MEASREQ_STA_STATS_REQ: fptr = ieee80211_rrm_send_stastats_resp(rrm,&rm_rsp->rsp_ies[0]); break; case IEEE80211_MEASREQ_NOISE_HISTOGRAM_REQ: fptr = ieee80211_rrm_send_nhist_resp(rrm,&rm_rsp->rsp_ies[0]); break; case IEEE80211_MEASREQ_LCI_REQ: fptr = ieee80211_rrm_send_lci_resp(rrm, &rm_rsp->rsp_ies[0]); break; case IEEE80211_MEASREQ_OTHER: measrsp = (struct ieee80211_measrsp_ie *)(&rm_rsp->rsp_ies[0]); measrsp->id = IEEE80211_ELEMID_MEASREP; measrsp->token=params->rep_dialogtoken; measrsp->rspmode |= params->reject_mode; measrsp->rsptype = params->reject_type; fptr = (u_int8_t *)(&measrsp->rsp[0]); measrsp->len = fptr -(u_int8_t *)(&measrsp->token); break; default: return; } if(IEEE80211_ADDR_EQ(ni->ni_macaddr, vap->iv_myaddr)) { /* self report */ ieee80211_rrm_recv_action(vap,ni,IEEE80211_ACTION_RM_RESP,frm,(fptr - frm)); OS_FREE(wbuf); } else { wbuf_set_pktlen(wbuf, (fptr -(u_int8_t*)(wbuf_header(wbuf)))); ieee80211_send_mgmt(vap, ni, wbuf, false); } rrm->rrm_in_progress = 0; /* making module available */ ieee80211_rrm_free_report(rrm); RRM_FUNCTION_EXIT; return; }
/* * Allocate a beacon frame and fillin the appropriate bits. */ struct sk_buff * ieee80211_beacon_alloc(struct ieee80211_node *ni, struct ieee80211_beacon_offsets *bo) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct ieee80211_frame *wh; struct sk_buff *skb; int pktlen; u_int8_t *frm; struct ieee80211_rateset *rs; /* * beacon frame format * [8] time stamp * [2] beacon interval * [2] capability information * [tlv] ssid * [tlv] supported rates * [7] FH/DS parameter set * [tlv] IBSS/TIM parameter set * [tlv] country code * [3] power constraint * [5] channel switch announcement * [3] extended rate phy (ERP) * [tlv] extended supported rates * [tlv] WME parameters * [tlv] WPA/RSN parameters * [tlv] Atheros Advanced Capabilities * [tlv] AtherosXR parameters * XXX Vendor-specific OIDs (e.g. Atheros) * NB: we allocate the max space required for the TIM bitmap. */ rs = &ni->ni_rates; pktlen = 8 /* time stamp */ + sizeof(u_int16_t) /* beacon interval */ + sizeof(u_int16_t) /* capability information */ + 2 + ni->ni_esslen /* ssid */ + 2 + IEEE80211_RATE_SIZE /* supported rates */ + 7 /* FH/DS parameters max(7,3) */ + 2 + 4 + vap->iv_tim_len /* IBSS/TIM parameter set*/ + ic->ic_country_ie.country_len + 2 /* country code */ + 3 /* power constraint */ + 5 /* channel switch announcement */ + 3 /* ERP */ + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) /* Ext. Supp. Rates */ + (vap->iv_caps & IEEE80211_C_WME ? /* WME */ sizeof(struct ieee80211_wme_param) : 0) + (vap->iv_caps & IEEE80211_C_WPA ? /* WPA 1+2 */ 2 * sizeof(struct ieee80211_ie_wpa) : 0) + sizeof(struct ieee80211_ie_athAdvCap) #ifdef ATH_SUPERG_XR + (ic->ic_ath_cap & IEEE80211_ATHC_XR ? /* XR */ sizeof(struct ieee80211_xr_param) : 0) #endif ; skb = ieee80211_getmgtframe(&frm, pktlen); if (skb == NULL) { IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni, "%s: cannot get buf; size %u", __func__, pktlen); vap->iv_stats.is_tx_nobuf++; return NULL; } frm = ieee80211_beacon_init(ni, bo, frm); skb_trim(skb, frm - skb->data); wh = (struct ieee80211_frame *) skb_push(skb, sizeof(struct ieee80211_frame)); wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON; wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; wh->i_dur = 0; IEEE80211_ADDR_COPY(wh->i_addr1, ic->ic_dev->broadcast); IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid); *(u_int16_t *)wh->i_seq = 0; return skb; }