Ejemplo n.º 1
0
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();
	}
}
Ejemplo n.º 2
0
/* 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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
/*
 * 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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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;
    }
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
/* 
 * 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);
}
Ejemplo n.º 12
0
/* 
 * 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);
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
/*
 * 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();
}
Ejemplo n.º 16
0
/*
 * 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);
}
Ejemplo n.º 17
0
/*
 * 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;
}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 19
0
/*
 * 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;
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
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 *) &params),num_vaps);  
        err = params.err;
    }

    /* TBD: Always reset the hardware? */
    err = ic->ic_reset(ic);
    if (err)
        return err;

    return err;
}
Ejemplo n.º 22
0
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));
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
/*
 * 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();
}
Ejemplo n.º 26
0
/*
 * 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;
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
/**
 * @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;
}
Ejemplo n.º 29
0
/*
 * 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;
}
Ejemplo n.º 30
0
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();
	}
}