예제 #1
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);
}
예제 #2
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);
}
예제 #3
0
int wlan_add_sta_node(wlan_if_t vap, const u_int8_t *macaddr, u_int16_t auth_alg)
{
    struct ieee80211_node *ni;

    ni = ieee80211_vap_find_node(vap, macaddr);
    if (ni == NULL) {
        ni = ieee80211_dup_bss(vap, macaddr);
    }

    if (ni == NULL) {
        return -ENOMEM;
    }
    /* claim node immediately */
    ieee80211_free_node(ni);
    return 0;
}
예제 #4
0
/*
 * Return a reference to the appropriate node for sending
 * a data frame.  This handles node discovery in adhoc networks.
 *
 * Drivers will call this, so increase the reference count before
 * returning the node.
 */
struct ieee80211_node *
ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr)
{
#ifndef IEEE80211_STA_ONLY
	struct ieee80211_node *ni;
	int s;
#endif

	/*
	 * The destination address should be in the node table
	 * unless we are operating in station mode or this is a
	 * multicast/broadcast frame.
	 */
	if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr))
		return ieee80211_ref_node(ic->ic_bss);

#ifndef IEEE80211_STA_ONLY
	s = splnet();
	ni = ieee80211_find_node(ic, macaddr);
	splx(s);
	if (ni == NULL) {
		if (ic->ic_opmode != IEEE80211_M_IBSS &&
		    ic->ic_opmode != IEEE80211_M_AHDEMO)
			return NULL;

		/*
		 * Fake up a node; this handles node discovery in
		 * adhoc mode.  Note that for the driver's benefit
		 * we we treat this like an association so the driver
		 * has an opportunity to setup its private state.
		 *
		 * XXX need better way to handle this; issue probe
		 *     request so we can deduce rate set, etc.
		 */
		if ((ni = ieee80211_dup_bss(ic, macaddr)) == NULL)
			return NULL;
		/* XXX no rate negotiation; just dup */
		ni->ni_rates = ic->ic_bss->ni_rates;
		ni->ni_txrate = 0;
		if (ic->ic_newassoc)
			(*ic->ic_newassoc)(ic, ni, 1);
	}
	return ieee80211_ref_node(ni);
#else
	return NULL;	/* can't get there */
#endif	/* IEEE80211_STA_ONLY */
}
예제 #5
0
/*
 * Return a reference to the appropriate node for sending
 * a data frame.  This handles node discovery in adhoc networks.
 *
 * Drivers will call this, so increase the reference count before
 * returning the node.
 */
struct ieee80211_node *
ieee80211_find_txnode(struct ieee80211com *ic, u_int8_t *macaddr)
{
	struct ieee80211_node *ni;

	/*
	 * The destination address should be in the node table
	 * unless we are operating in station mode or this is a
	 * multicast/broadcast frame.
	 */
	if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr))
		return ieee80211_ref_node(ic->ic_bss);

	/* XXX can't hold lock across dup_bss 'cuz of recursive locking */
	IEEE80211_NODE_LOCK(ic);
	ni = ieee80211_find_node(ic, macaddr);
	IEEE80211_NODE_UNLOCK(ic);
	if (ni == NULL) {
		if (ic->ic_opmode != IEEE80211_M_IBSS &&
		    ic->ic_opmode != IEEE80211_M_AHDEMO)
			return NULL;

		/*
		 * Fake up a node; this handles node discovery in
		 * adhoc mode.  Note that for the driver's benefit
		 * we we treat this like an association so the driver
		 * has an opportunity to setup its private state.
		 *
		 * XXX need better way to handle this; issue probe
		 *     request so we can deduce rate set, etc.
		 */
		if ((ni = ieee80211_dup_bss(ic, macaddr)) == NULL)
			return NULL;
		/* XXX no rate negotiation; just dup */
		ni->ni_rates = ic->ic_bss->ni_rates;
		if (ic->ic_newassoc)
			(*ic->ic_newassoc)(ic, ni, 1);
	}
	return ieee80211_ref_node(ni);
}
예제 #6
0
wlan_btamp_conn_sm_t
wlan_btamp_conn_sm_create(wlan_if_t            vaphandle,
                          wlan_btamp_conn_sm_t *linkHandle,
                          u_int8_t             *peer_addr, 
                          bool                 initiating)
{
    wlan_btamp_conn_sm_t     sm;
    struct ieee80211vap      *vap = vaphandle;
    osdev_t                  oshandle = vap->iv_ic->ic_osdev;
    struct ieee80211_node    *ni;

    sm = (wlan_btamp_conn_sm_t) OS_MALLOC(oshandle, sizeof(struct _wlan_btamp_conn_sm), 0);
    if (!sm) {
        return NULL;
    }
    OS_MEMZERO(sm, sizeof(struct _wlan_btamp_conn_sm));

    sm->os_handle = oshandle;
    sm->vap_handle = vaphandle;
    OS_MEMCPY(sm->peer, peer_addr, IEEE80211_ADDR_LEN);
    sm->initiating = initiating;
    sm->hsm_handle = ieee80211_sm_create(oshandle,
                                         "btamp_conn",
                                         (void *) sm,
                                         IEEE80211_BTAMP_CONN_STATE_BEACONING,
                                         ieee80211_btamp_conn_sm_info,
                                         sizeof(ieee80211_btamp_conn_sm_info)/sizeof(ieee80211_state_info),
                                         MAX_QUEUED_EVENTS,
                                         sizeof(u_int32_t) /* event data of size int */, 
                                         MESGQ_PRIORITY_HIGH,
                                         IEEE80211_HSM_ASYNCHRONOUS, /* run the SM asynchronously */
                                         ieee80211_btamp_conn_sm_debug_print,
                                         btamp_event_name,
                                         IEEE80211_N(btamp_event_name));
    if (!sm->hsm_handle) {
        OS_FREE(sm);
        IEEE80211_DPRINTF(vaphandle, IEEE80211_MSG_STATE,
            "%s : ieee80211_sm_create failed\n", __func__);
        return NULL;
    }

    sm->max_assoc_attempts = MAX_ASSOC_ATTEMPTS;
    sm->max_auth_attempts =  MAX_AUTH_ATTEMPTS;
    sm->max_mgmt_time =  MAX_MGMT_TIME;
    OS_INIT_TIMER(oshandle, &(sm->sm_timer), btamp_conn_sm_timer_handler, (void *)sm);

    /* Register MLME event handlers */
    wlan_vap_register_mlme_event_handlers(vaphandle, (os_if_t)linkHandle, &btamp_mlme_evt_handler);

    /* Create a node for the peer mac address */
    ni = ieee80211_dup_bss(vap, peer_addr);
    if (ni) {
        if (initiating) {
            IEEE80211_ADDR_COPY(ni->ni_bssid, peer_addr);

            /* Set up SSID */
            snprintf((char *)ni->ni_essid, 22, "AMP-%02x-%02x-%02x-%02x-%02x-%02x",
                     peer_addr[0], peer_addr[1], peer_addr[2],
                     peer_addr[3], peer_addr[4], peer_addr[5]);
            ni->ni_esslen = 21;
            ni->ni_flags |= IEEE80211_NODE_ERP; // Mark the node as ERP
        }
        ieee80211_free_node(ni); /* Decrement the extra ref count */
    }

    return sm;
}