示例#1
0
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
}
示例#2
0
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(&params, 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, &params);
}
示例#3
0
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;
}
示例#4
0
/*
 * 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;
}