Several fixes hostap for awi driver:
- aging ang clear inactivity stations - DTIM field in beacon/probe response. - ignore IFF_PROMISC for hostap mode, since 802.11 has 3 address fields, so that promisc mode is not required for AP function.
This commit is contained in:
parent
c0a8cbae7c
commit
26ebf5f371
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: awi.c,v 1.45 2002/09/02 13:37:35 onoe Exp $ */
|
/* $NetBSD: awi.c,v 1.46 2002/09/03 14:54:00 onoe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.45 2002/09/02 13:37:35 onoe Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.46 2002/09/03 14:54:00 onoe Exp $");
|
||||||
|
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
#include "bpfilter.h"
|
#include "bpfilter.h"
|
||||||
|
@ -491,9 +491,9 @@ awi_init(struct ifnet *ifp)
|
||||||
(ic->ic_flags & IEEE80211_F_HOSTAP) ? 1 : 0;
|
(ic->ic_flags & IEEE80211_F_HOSTAP) ? 1 : 0;
|
||||||
memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
|
memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
|
||||||
sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
|
sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
|
||||||
sc->sc_mib_mac.aDesired_ESS_ID[1] = sc->sc_ic.ic_des_esslen;
|
sc->sc_mib_mac.aDesired_ESS_ID[1] = ic->ic_des_esslen;
|
||||||
memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], sc->sc_ic.ic_des_essid,
|
memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], ic->ic_des_essid,
|
||||||
sc->sc_ic.ic_des_esslen);
|
ic->ic_des_esslen);
|
||||||
|
|
||||||
if ((error = awi_mode_init(sc)) != 0) {
|
if ((error = awi_mode_init(sc)) != 0) {
|
||||||
DPRINTF(("awi_init: awi_mode_init failed %d\n", error));
|
DPRINTF(("awi_init: awi_mode_init failed %d\n", error));
|
||||||
|
@ -533,8 +533,8 @@ awi_init(struct ifnet *ifp)
|
||||||
ifp->if_flags |= IFF_RUNNING;
|
ifp->if_flags |= IFF_RUNNING;
|
||||||
ifp->if_flags &= ~IFF_OACTIVE;
|
ifp->if_flags &= ~IFF_OACTIVE;
|
||||||
|
|
||||||
if (((sc->sc_ic.ic_flags & IEEE80211_F_ADHOC) && sc->sc_no_bssid) ||
|
if (((ic->ic_flags & IEEE80211_F_ADHOC) && sc->sc_no_bssid) ||
|
||||||
(sc->sc_ic.ic_flags & IEEE80211_F_HOSTAP)) {
|
(ic->ic_flags & IEEE80211_F_HOSTAP)) {
|
||||||
bs->bs_chan = ic->ic_ibss_chan;
|
bs->bs_chan = ic->ic_ibss_chan;
|
||||||
bs->bs_intval = ic->ic_lintval;
|
bs->bs_intval = ic->ic_lintval;
|
||||||
bs->bs_rssi = 0;
|
bs->bs_rssi = 0;
|
||||||
|
@ -547,7 +547,7 @@ awi_init(struct ifnet *ifp)
|
||||||
ic->ic_sup_rates[i];
|
ic->ic_sup_rates[i];
|
||||||
}
|
}
|
||||||
memcpy(bs->bs_macaddr, ic->ic_myaddr, IEEE80211_ADDR_LEN);
|
memcpy(bs->bs_macaddr, ic->ic_myaddr, IEEE80211_ADDR_LEN);
|
||||||
if (sc->sc_ic.ic_flags & IEEE80211_F_HOSTAP) {
|
if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
||||||
memcpy(bs->bs_bssid, ic->ic_myaddr, IEEE80211_ADDR_LEN);
|
memcpy(bs->bs_bssid, ic->ic_myaddr, IEEE80211_ADDR_LEN);
|
||||||
bs->bs_esslen = ic->ic_des_esslen;
|
bs->bs_esslen = ic->ic_des_esslen;
|
||||||
memcpy(bs->bs_essid, ic->ic_des_essid, bs->bs_esslen);
|
memcpy(bs->bs_essid, ic->ic_des_essid, bs->bs_esslen);
|
||||||
|
@ -975,7 +975,8 @@ awi_mode_init(struct awi_softc *sc)
|
||||||
/* reinitialize muticast filter */
|
/* reinitialize muticast filter */
|
||||||
n = 0;
|
n = 0;
|
||||||
sc->sc_mib_local.Accept_All_Multicast_Dis = 0;
|
sc->sc_mib_local.Accept_All_Multicast_Dis = 0;
|
||||||
if (ifp->if_flags & IFF_PROMISC) {
|
if ((sc->sc_ic.ic_flags & IEEE80211_F_HOSTAP) == 0 &&
|
||||||
|
(ifp->if_flags & IFF_PROMISC)) {
|
||||||
sc->sc_mib_mac.aPromiscuous_Enable = 1;
|
sc->sc_mib_mac.aPromiscuous_Enable = 1;
|
||||||
goto set_mib;
|
goto set_mib;
|
||||||
}
|
}
|
||||||
|
@ -1264,8 +1265,14 @@ awi_hw_init(struct awi_softc *sc)
|
||||||
printf(" (lost interrupt)\n");
|
printf(" (lost interrupt)\n");
|
||||||
else
|
else
|
||||||
printf(" (command timeout)\n");
|
printf(" (command timeout)\n");
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
return error;
|
|
||||||
|
/* Initialize VBM */
|
||||||
|
awi_write_1(sc, AWI_VBM_OFFSET, 0);
|
||||||
|
awi_write_1(sc, AWI_VBM_LENGTH, 1);
|
||||||
|
awi_write_1(sc, AWI_VBM_BITMAP, 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1324,11 +1331,19 @@ awi_init_mibs(struct awi_softc *sc)
|
||||||
}
|
}
|
||||||
sc->sc_cur_chan = cs->cs_def;
|
sc->sc_cur_chan = cs->cs_def;
|
||||||
|
|
||||||
memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
|
|
||||||
sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
|
|
||||||
sc->sc_mib_local.Fragmentation_Dis = 1;
|
sc->sc_mib_local.Fragmentation_Dis = 1;
|
||||||
sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
|
sc->sc_mib_local.Add_PLCP_Dis = 0;
|
||||||
|
sc->sc_mib_local.MAC_Hdr_Prsv = 1;
|
||||||
|
sc->sc_mib_local.Rx_Mgmt_Que_En = 0;
|
||||||
|
sc->sc_mib_local.Re_Assembly_Dis = 1;
|
||||||
|
sc->sc_mib_local.Strip_PLCP_Dis = 0;
|
||||||
sc->sc_mib_local.Power_Saving_Mode_Dis = 1;
|
sc->sc_mib_local.Power_Saving_Mode_Dis = 1;
|
||||||
|
sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
|
||||||
|
sc->sc_mib_local.Check_Seq_Cntl_Dis = 1;
|
||||||
|
sc->sc_mib_local.Flush_CFP_Queue_On_CF_End = 0;
|
||||||
|
sc->sc_mib_local.Network_Mode = 1;
|
||||||
|
sc->sc_mib_local.PWD_Lvl = 0;
|
||||||
|
sc->sc_mib_local.CFP_Mode = 0;
|
||||||
|
|
||||||
/* allocate buffers */
|
/* allocate buffers */
|
||||||
sc->sc_txbase = AWI_BUFFERS;
|
sc->sc_txbase = AWI_BUFFERS;
|
||||||
|
@ -1341,8 +1356,15 @@ awi_init_mibs(struct awi_softc *sc)
|
||||||
LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend);
|
LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend);
|
||||||
LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size,
|
LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size,
|
||||||
AWI_BUFFERS_END - sc->sc_txend);
|
AWI_BUFFERS_END - sc->sc_txend);
|
||||||
sc->sc_mib_local.Network_Mode = 1;
|
|
||||||
sc->sc_mib_local.Acting_as_AP = 0;
|
sc->sc_mib_local.Acting_as_AP = 0;
|
||||||
|
sc->sc_mib_local.Fill_CFP = 0;
|
||||||
|
|
||||||
|
memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
|
||||||
|
sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
|
||||||
|
|
||||||
|
sc->sc_mib_mgt.aPower_Mgt_Mode = 0;
|
||||||
|
sc->sc_mib_mgt.aDTIM_Period = 1;
|
||||||
|
LE_WRITE_2(&sc->sc_mib_mgt.aATIM_Window, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: awireg.h,v 1.6 2002/08/05 06:55:07 onoe Exp $ */
|
/* $NetBSD: awireg.h,v 1.7 2002/09/03 14:54:01 onoe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||||
|
@ -258,7 +258,9 @@
|
||||||
#define AWI_DRV_RXLED 0x40
|
#define AWI_DRV_RXLED 0x40
|
||||||
#define AWI_DRV_TXLED 0x80
|
#define AWI_DRV_TXLED 0x80
|
||||||
|
|
||||||
#define AWI_VBM 0x500 /* Virtual Bit Map */
|
#define AWI_VBM_OFFSET 0x500 /* Virtual Bit Map */
|
||||||
|
#define AWI_VBM_LENGTH 0x501
|
||||||
|
#define AWI_VBM_BITMAP 0x502
|
||||||
|
|
||||||
#define AWI_BUFFERS 0x600 /* Buffers */
|
#define AWI_BUFFERS 0x600 /* Buffers */
|
||||||
#define AWI_BUFFERS_END 0x6000
|
#define AWI_BUFFERS_END 0x6000
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_ieee80211.h,v 1.16 2002/09/02 13:37:35 onoe Exp $ */
|
/* $NetBSD: if_ieee80211.h,v 1.17 2002/09/03 14:54:00 onoe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -334,6 +334,8 @@ struct ieee80211_auth {
|
||||||
#define IEEE80211_ASCAN_WAIT 2 /* active scan wait */
|
#define IEEE80211_ASCAN_WAIT 2 /* active scan wait */
|
||||||
#define IEEE80211_PSCAN_WAIT 5 /* passive scan wait */
|
#define IEEE80211_PSCAN_WAIT 5 /* passive scan wait */
|
||||||
#define IEEE80211_TRANS_WAIT 5 /* transition wait */
|
#define IEEE80211_TRANS_WAIT 5 /* transition wait */
|
||||||
|
#define IEEE80211_INACT_WAIT 5 /* inactivity timer interval */
|
||||||
|
#define IEEE80211_INACT_MAX (300/IEEE80211_INACT_WAIT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure for IEEE 802.11 drivers.
|
* Structure for IEEE 802.11 drivers.
|
||||||
|
@ -382,6 +384,7 @@ struct ieee80211_bss {
|
||||||
u_int16_t bs_txseq; /* seq to be transmitted */
|
u_int16_t bs_txseq; /* seq to be transmitted */
|
||||||
u_int16_t bs_rxseq; /* seq previous received */
|
u_int16_t bs_rxseq; /* seq previous received */
|
||||||
int bs_fails; /* failure count to associate */
|
int bs_fails; /* failure count to associate */
|
||||||
|
int bs_inact; /* inactivity mark count */
|
||||||
int bs_txrate; /* index to bs_rates[] */
|
int bs_txrate; /* index to bs_rates[] */
|
||||||
void *bs_private; /* driver private */
|
void *bs_private; /* driver private */
|
||||||
};
|
};
|
||||||
|
@ -421,6 +424,7 @@ struct ieee80211com {
|
||||||
u_int16_t ic_lintval; /* listen interval */
|
u_int16_t ic_lintval; /* listen interval */
|
||||||
int ic_mgt_timer; /* mgmt timeout */
|
int ic_mgt_timer; /* mgmt timeout */
|
||||||
int ic_scan_timer; /* scant wait */
|
int ic_scan_timer; /* scant wait */
|
||||||
|
int ic_inact_timer; /* inactivity timer wait */
|
||||||
int ic_des_esslen;
|
int ic_des_esslen;
|
||||||
u_int8_t ic_des_essid[IEEE80211_NWID_LEN];
|
u_int8_t ic_des_essid[IEEE80211_NWID_LEN];
|
||||||
struct ieee80211_wepkey ic_nw_keys[IEEE80211_WEP_NKID];
|
struct ieee80211_wepkey ic_nw_keys[IEEE80211_WEP_NKID];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_ieee80211subr.c,v 1.11 2002/09/02 13:37:35 onoe Exp $ */
|
/* $NetBSD: if_ieee80211subr.c,v 1.12 2002/09/03 14:54:00 onoe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_ieee80211subr.c,v 1.11 2002/09/02 13:37:35 onoe Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_ieee80211subr.c,v 1.12 2002/09/03 14:54:00 onoe Exp $");
|
||||||
|
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
#include "bpfilter.h"
|
#include "bpfilter.h"
|
||||||
|
@ -294,6 +294,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, int rssi, u_int32_t rstamp)
|
||||||
/* duplicate, silently discarded */
|
/* duplicate, silently discarded */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
bs->bs_inact = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
|
switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
|
||||||
|
@ -362,9 +363,26 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, int rssi, u_int32_t rstamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_DEBUG) {
|
if (ifp->if_flags & IFF_DEBUG) {
|
||||||
if (!(ic->ic_flags & IEEE80211_F_ADHOC) ||
|
/* avoid to print too many frames */
|
||||||
ic->ic_state == IEEE80211_S_SCAN ||
|
int doprint = 0;
|
||||||
subtype != IEEE80211_FC0_SUBTYPE_BEACON)
|
|
||||||
|
switch (subtype) {
|
||||||
|
case IEEE80211_FC0_SUBTYPE_BEACON:
|
||||||
|
if (ic->ic_state == IEEE80211_S_SCAN)
|
||||||
|
doprint = 1;
|
||||||
|
break;
|
||||||
|
case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
|
||||||
|
if (ic->ic_flags & IEEE80211_F_ADHOC)
|
||||||
|
doprint = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
doprint = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef IEEE80211_DEBUG
|
||||||
|
doprint += ieee80211_debug;
|
||||||
|
#endif
|
||||||
|
if (doprint)
|
||||||
printf("%s: received %s from %s rssi %d\n",
|
printf("%s: received %s from %s rssi %d\n",
|
||||||
ifp->if_xname,
|
ifp->if_xname,
|
||||||
ieee80211_mgt_subtype_name[subtype
|
ieee80211_mgt_subtype_name[subtype
|
||||||
|
@ -408,6 +426,7 @@ ieee80211_mgmt_output(struct ifnet *ifp, struct ieee80211_bss *bs,
|
||||||
|
|
||||||
if (bs == NULL)
|
if (bs == NULL)
|
||||||
bs = &ic->ic_bss;
|
bs = &ic->ic_bss;
|
||||||
|
bs->bs_inact = 0;
|
||||||
M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
|
M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@ -422,12 +441,17 @@ ieee80211_mgmt_output(struct ifnet *ifp, struct ieee80211_bss *bs,
|
||||||
memcpy(wh->i_addr2, ic->ic_myaddr, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr2, ic->ic_myaddr, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr3, bs->bs_bssid, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr3, bs->bs_bssid, IEEE80211_ADDR_LEN);
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_DEBUG)
|
if (ifp->if_flags & IFF_DEBUG) {
|
||||||
printf("%s: sending %s to %s\n", ifp->if_xname,
|
/* avoid to print too many frames */
|
||||||
ieee80211_mgt_subtype_name[
|
if ((ic->ic_flags & IEEE80211_F_ADHOC) ||
|
||||||
(type & IEEE80211_FC0_SUBTYPE_MASK)
|
(type & IEEE80211_FC0_SUBTYPE_MASK) !=
|
||||||
>> IEEE80211_FC0_SUBTYPE_SHIFT],
|
IEEE80211_FC0_SUBTYPE_PROBE_RESP)
|
||||||
ether_sprintf(bs->bs_macaddr));
|
printf("%s: sending %s to %s\n", ifp->if_xname,
|
||||||
|
ieee80211_mgt_subtype_name[
|
||||||
|
(type & IEEE80211_FC0_SUBTYPE_MASK)
|
||||||
|
>> IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||||
|
ether_sprintf(bs->bs_macaddr));
|
||||||
|
}
|
||||||
IF_ENQUEUE(&ic->ic_mgtq, m);
|
IF_ENQUEUE(&ic->ic_mgtq, m);
|
||||||
ifp->if_timer = 1;
|
ifp->if_timer = 1;
|
||||||
(*ifp->if_start)(ifp);
|
(*ifp->if_start)(ifp);
|
||||||
|
@ -441,6 +465,7 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m)
|
||||||
struct ether_header eh;
|
struct ether_header eh;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct llc *llc;
|
struct llc *llc;
|
||||||
|
struct ieee80211_bss *bs;
|
||||||
|
|
||||||
if (m->m_len < sizeof(struct ether_header)) {
|
if (m->m_len < sizeof(struct ether_header)) {
|
||||||
m = m_pullup(m, sizeof(struct ether_header));
|
m = m_pullup(m, sizeof(struct ether_header));
|
||||||
|
@ -448,6 +473,25 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
|
memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
|
||||||
|
|
||||||
|
if ((eh.ether_dhost[0] & 0x01) == 0 &&
|
||||||
|
((ic->ic_flags & IEEE80211_F_ADHOC) ||
|
||||||
|
(ic->ic_flags & IEEE80211_F_HOSTAP))) {
|
||||||
|
TAILQ_FOREACH(bs, &ic->ic_scan, bs_list) {
|
||||||
|
if (memcmp(bs->bs_macaddr, eh.ether_dhost,
|
||||||
|
IEEE80211_ADDR_LEN) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bs == NULL ||
|
||||||
|
((ic->ic_flags & IEEE80211_F_HOSTAP) &&
|
||||||
|
bs->bs_associd == 0)) {
|
||||||
|
m_freem(m);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
bs = &ic->ic_bss;
|
||||||
|
bs->bs_inact = 0;
|
||||||
|
|
||||||
m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
|
m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
|
||||||
llc = mtod(m, struct llc *);
|
llc = mtod(m, struct llc *);
|
||||||
llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
|
llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
|
||||||
|
@ -463,21 +507,21 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m)
|
||||||
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
|
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
|
||||||
*(u_int16_t *)wh->i_dur = 0;
|
*(u_int16_t *)wh->i_dur = 0;
|
||||||
*(u_int16_t *)wh->i_seq =
|
*(u_int16_t *)wh->i_seq =
|
||||||
htole16(ic->ic_bss.bs_txseq << IEEE80211_SEQ_SEQ_SHIFT);
|
htole16(bs->bs_txseq << IEEE80211_SEQ_SEQ_SHIFT);
|
||||||
ic->ic_bss.bs_txseq++;
|
bs->bs_txseq++;
|
||||||
if (ic->ic_flags & IEEE80211_F_ADHOC) {
|
if (ic->ic_flags & IEEE80211_F_ADHOC) {
|
||||||
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
|
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
|
||||||
memcpy(wh->i_addr1, eh.ether_dhost, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr1, eh.ether_dhost, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr2, eh.ether_shost, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr2, eh.ether_shost, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr3, ic->ic_bss.bs_bssid, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr3, bs->bs_bssid, IEEE80211_ADDR_LEN);
|
||||||
} else if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
} else if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
||||||
wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
|
wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
|
||||||
memcpy(wh->i_addr1, eh.ether_dhost, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr1, eh.ether_dhost, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr2, ic->ic_bss.bs_bssid, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr2, bs->bs_bssid, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr3, eh.ether_shost, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr3, eh.ether_shost, IEEE80211_ADDR_LEN);
|
||||||
} else {
|
} else {
|
||||||
wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
|
wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
|
||||||
memcpy(wh->i_addr1, ic->ic_bss.bs_bssid, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr1, bs->bs_bssid, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr2, eh.ether_shost, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr2, eh.ether_shost, IEEE80211_ADDR_LEN);
|
||||||
memcpy(wh->i_addr3, eh.ether_dhost, IEEE80211_ADDR_LEN);
|
memcpy(wh->i_addr3, eh.ether_dhost, IEEE80211_ADDR_LEN);
|
||||||
}
|
}
|
||||||
|
@ -817,6 +861,7 @@ void
|
||||||
ieee80211_watchdog(struct ifnet *ifp)
|
ieee80211_watchdog(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
struct ieee80211com *ic = (void *)ifp;
|
struct ieee80211com *ic = (void *)ifp;
|
||||||
|
struct ieee80211_bss *bs, *nextbs;
|
||||||
|
|
||||||
if (ic->ic_scan_timer) {
|
if (ic->ic_scan_timer) {
|
||||||
if (--ic->ic_scan_timer == 0) {
|
if (--ic->ic_scan_timer == 0) {
|
||||||
|
@ -828,7 +873,33 @@ ieee80211_watchdog(struct ifnet *ifp)
|
||||||
if (--ic->ic_mgt_timer == 0)
|
if (--ic->ic_mgt_timer == 0)
|
||||||
ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1);
|
ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1);
|
||||||
}
|
}
|
||||||
if (ic->ic_scan_timer != 0 || ic->ic_mgt_timer != 0)
|
if (ic->ic_inact_timer) {
|
||||||
|
if (--ic->ic_inact_timer == 0) {
|
||||||
|
for (bs = TAILQ_FIRST(&ic->ic_scan); bs != NULL; ) {
|
||||||
|
if (++bs->bs_inact <= IEEE80211_INACT_MAX) {
|
||||||
|
bs = TAILQ_NEXT(bs, bs_list);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s deauthenticate"
|
||||||
|
" (reason %d)\n",
|
||||||
|
ifp->if_xname,
|
||||||
|
ether_sprintf(bs->bs_macaddr),
|
||||||
|
IEEE80211_REASON_AUTH_EXPIRE);
|
||||||
|
nextbs = TAILQ_NEXT(bs, bs_list);
|
||||||
|
IEEE80211_SEND_MGMT(ic, bs,
|
||||||
|
IEEE80211_FC0_SUBTYPE_DEAUTH,
|
||||||
|
IEEE80211_REASON_AUTH_EXPIRE);
|
||||||
|
TAILQ_REMOVE(&ic->ic_scan, bs, bs_list);
|
||||||
|
free(bs, M_DEVBUF);
|
||||||
|
bs = nextbs;
|
||||||
|
}
|
||||||
|
if (!TAILQ_EMPTY(&ic->ic_scan))
|
||||||
|
ic->ic_inact_timer = IEEE80211_INACT_WAIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ic->ic_scan_timer != 0 || ic->ic_mgt_timer != 0 ||
|
||||||
|
ic->ic_inact_timer != 0)
|
||||||
ifp->if_timer = 1;
|
ifp->if_timer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,6 +1086,9 @@ ieee80211_alloc_bss(struct ieee80211com *ic, int copy)
|
||||||
memset(bs->bs_private, 0, ic->ic_bss_privlen);
|
memset(bs->bs_private, 0, ic->ic_bss_privlen);
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_TAIL(&ic->ic_scan, bs, bs_list);
|
TAILQ_INSERT_TAIL(&ic->ic_scan, bs, bs_list);
|
||||||
|
if ((ic->ic_flags & IEEE80211_F_HOSTAP) ||
|
||||||
|
(ic->ic_flags & IEEE80211_F_ADHOC))
|
||||||
|
ic->ic_inact_timer = IEEE80211_INACT_WAIT;
|
||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1028,6 +1102,7 @@ ieee80211_free_scan(struct ifnet *ifp)
|
||||||
TAILQ_REMOVE(&ic->ic_scan, bs, bs_list);
|
TAILQ_REMOVE(&ic->ic_scan, bs, bs_list);
|
||||||
free(bs, M_DEVBUF);
|
free(bs, M_DEVBUF);
|
||||||
}
|
}
|
||||||
|
ic->ic_inact_timer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1177,6 +1252,12 @@ ieee80211_send_prresp(struct ieee80211com *ic, struct ieee80211_bss *bs0,
|
||||||
*frm++ = 0; *frm++ = 0; /* TODO: ATIM window */
|
*frm++ = 0; *frm++ = 0; /* TODO: ATIM window */
|
||||||
} else {
|
} else {
|
||||||
/* TODO: TIM */
|
/* TODO: TIM */
|
||||||
|
*frm++ = IEEE80211_ELEMID_TIM;
|
||||||
|
*frm++ = 4; /* length */
|
||||||
|
*frm++ = 0; /* DTIM count */
|
||||||
|
*frm++ = 1; /* DTIM period */
|
||||||
|
*frm++ = 0; /* bitmap control */
|
||||||
|
*frm++ = 0; /* Partial Virtual Bitmap (variable length) */
|
||||||
}
|
}
|
||||||
/* TODO: check MHLEN limit */
|
/* TODO: check MHLEN limit */
|
||||||
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
|
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
|
||||||
|
@ -1213,8 +1294,12 @@ static int
|
||||||
ieee80211_send_deauth(struct ieee80211com *ic, struct ieee80211_bss *bs,
|
ieee80211_send_deauth(struct ieee80211com *ic, struct ieee80211_bss *bs,
|
||||||
int type, int reason)
|
int type, int reason)
|
||||||
{
|
{
|
||||||
|
struct ifnet *ifp = &ic->ic_if;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s deauthenticate (reason %d)\n",
|
||||||
|
ifp->if_xname, ether_sprintf(bs->bs_macaddr), reason);
|
||||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@ -1337,10 +1422,14 @@ ieee80211_send_asresp(struct ieee80211com *ic, struct ieee80211_bss *bs,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ieee80211_send_disassoc(struct ieee80211com *ic, struct ieee80211_bss *bs,
|
ieee80211_send_disassoc(struct ieee80211com *ic, struct ieee80211_bss *bs,
|
||||||
int reason, int dummy)
|
int type, int reason)
|
||||||
{
|
{
|
||||||
|
struct ifnet *ifp = &ic->ic_if;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s disassociate (reason %d)\n",
|
||||||
|
ifp->if_xname, ether_sprintf(bs->bs_macaddr), reason);
|
||||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@ -1479,9 +1568,12 @@ ieee80211_recv_prreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
struct ieee80211_bss *bs;
|
struct ieee80211_bss *bs;
|
||||||
u_int8_t *frm, *efrm, *ssid, *rates;
|
u_int8_t *frm, *efrm, *ssid, *rates;
|
||||||
u_int8_t rate;
|
u_int8_t rate;
|
||||||
|
int allocbs;
|
||||||
|
|
||||||
if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0 ||
|
if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0 &&
|
||||||
(ic->ic_state != IEEE80211_S_RUN))
|
(ic->ic_flags & IEEE80211_F_HOSTAP) == 0)
|
||||||
|
return;
|
||||||
|
if (ic->ic_state != IEEE80211_S_RUN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
|
@ -1533,7 +1625,9 @@ ieee80211_recv_prreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
DPRINTF(("ieee80211_recv_prreq: new req from %s\n",
|
DPRINTF(("ieee80211_recv_prreq: new req from %s\n",
|
||||||
ether_sprintf(wh->i_addr2)));
|
ether_sprintf(wh->i_addr2)));
|
||||||
memcpy(bs->bs_macaddr, wh->i_addr2, IEEE80211_ADDR_LEN);
|
memcpy(bs->bs_macaddr, wh->i_addr2, IEEE80211_ADDR_LEN);
|
||||||
}
|
allocbs = 1;
|
||||||
|
} else
|
||||||
|
allocbs = 0;
|
||||||
memset(bs->bs_rates, 0, IEEE80211_RATE_SIZE);
|
memset(bs->bs_rates, 0, IEEE80211_RATE_SIZE);
|
||||||
bs->bs_nrate = rates[1];
|
bs->bs_nrate = rates[1];
|
||||||
memcpy(bs->bs_rates, rates + 2, bs->bs_nrate);
|
memcpy(bs->bs_rates, rates + 2, bs->bs_nrate);
|
||||||
|
@ -1544,19 +1638,28 @@ ieee80211_recv_prreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
if (rate & IEEE80211_RATE_BASIC) {
|
if (rate & IEEE80211_RATE_BASIC) {
|
||||||
DPRINTF(("ieee80211_recv_prreq: rate negotiation failed: %s\n",
|
DPRINTF(("ieee80211_recv_prreq: rate negotiation failed: %s\n",
|
||||||
ether_sprintf(wh->i_addr2)));
|
ether_sprintf(wh->i_addr2)));
|
||||||
return;
|
} else {
|
||||||
|
IEEE80211_SEND_MGMT(ic, bs, IEEE80211_FC0_SUBTYPE_PROBE_RESP,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
if (allocbs && (ic->ic_flags & IEEE80211_F_HOSTAP)) {
|
||||||
|
TAILQ_REMOVE(&ic->ic_scan, bs, bs_list);
|
||||||
|
free(bs, M_DEVBUF);
|
||||||
|
if (TAILQ_EMPTY(&ic->ic_scan))
|
||||||
|
ic->ic_inact_timer = 0;
|
||||||
}
|
}
|
||||||
IEEE80211_SEND_MGMT(ic, bs, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
u_int32_t rstamp)
|
u_int32_t rstamp)
|
||||||
{
|
{
|
||||||
|
struct ifnet *ifp = &ic->ic_if;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct ieee80211_bss *bs;
|
struct ieee80211_bss *bs;
|
||||||
u_int8_t *frm, *efrm;
|
u_int8_t *frm, *efrm;
|
||||||
u_int16_t algo, seq, status;
|
u_int16_t algo, seq, status;
|
||||||
|
int allocbs;
|
||||||
|
|
||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
frm = (u_int8_t *)&wh[1];
|
frm = (u_int8_t *)&wh[1];
|
||||||
|
@ -1583,17 +1686,16 @@ ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ic->ic_flags & IEEE80211_F_ADHOC) {
|
if (ic->ic_flags & IEEE80211_F_ADHOC) {
|
||||||
if (ic->ic_state != IEEE80211_S_RUN)
|
if (ic->ic_state != IEEE80211_S_RUN || seq != 1)
|
||||||
return;
|
return;
|
||||||
if (seq == 1) {
|
ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH,
|
||||||
ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH,
|
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
|
||||||
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
||||||
if (ic->ic_state != IEEE80211_S_RUN)
|
if (ic->ic_state != IEEE80211_S_RUN || seq != 1)
|
||||||
return;
|
return;
|
||||||
|
allocbs = 0;
|
||||||
TAILQ_FOREACH(bs, &ic->ic_scan, bs_list) {
|
TAILQ_FOREACH(bs, &ic->ic_scan, bs_list) {
|
||||||
if (memcmp(bs->bs_macaddr, wh->i_addr2,
|
if (memcmp(bs->bs_macaddr, wh->i_addr2,
|
||||||
IEEE80211_ADDR_LEN) == 0)
|
IEEE80211_ADDR_LEN) == 0)
|
||||||
|
@ -1605,8 +1707,14 @@ ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
memcpy(bs->bs_macaddr, wh->i_addr2, IEEE80211_ADDR_LEN);
|
memcpy(bs->bs_macaddr, wh->i_addr2, IEEE80211_ADDR_LEN);
|
||||||
memcpy(bs->bs_bssid, ic->ic_bss.bs_bssid,
|
memcpy(bs->bs_bssid, ic->ic_bss.bs_bssid,
|
||||||
IEEE80211_ADDR_LEN);
|
IEEE80211_ADDR_LEN);
|
||||||
|
allocbs = 1;
|
||||||
}
|
}
|
||||||
IEEE80211_SEND_MGMT(ic, bs, IEEE80211_FC0_SUBTYPE_AUTH, 2);
|
IEEE80211_SEND_MGMT(ic, bs, IEEE80211_FC0_SUBTYPE_AUTH, 2);
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s %s authenticated\n",
|
||||||
|
ifp->if_xname,
|
||||||
|
(allocbs ? "newly" : "already"),
|
||||||
|
ether_sprintf(bs->bs_macaddr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ic->ic_state != IEEE80211_S_AUTH || seq != 2)
|
if (ic->ic_state != IEEE80211_S_AUTH || seq != 2)
|
||||||
|
@ -1631,11 +1739,12 @@ static void
|
||||||
ieee80211_recv_asreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
ieee80211_recv_asreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
u_int32_t rstamp)
|
u_int32_t rstamp)
|
||||||
{
|
{
|
||||||
|
struct ifnet *ifp = &ic->ic_if;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct ieee80211_bss *bs = &ic->ic_bss;
|
struct ieee80211_bss *bs = &ic->ic_bss;
|
||||||
u_int8_t *frm, *efrm, *ssid, *rates;
|
u_int8_t *frm, *efrm, *ssid, *rates;
|
||||||
u_int16_t capinfo, bintval;
|
u_int16_t capinfo, bintval;
|
||||||
int reassoc, resp;
|
int reassoc, resp, newassoc;
|
||||||
|
|
||||||
if ((ic->ic_flags & IEEE80211_F_HOSTAP) == 0 ||
|
if ((ic->ic_flags & IEEE80211_F_HOSTAP) == 0 ||
|
||||||
(ic->ic_state != IEEE80211_S_RUN))
|
(ic->ic_state != IEEE80211_S_RUN))
|
||||||
|
@ -1715,11 +1824,11 @@ ieee80211_recv_asreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
}
|
}
|
||||||
if (bs == NULL)
|
if (bs == NULL)
|
||||||
return;
|
return;
|
||||||
bs->bs_associd = 0;
|
|
||||||
if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 ||
|
if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 ||
|
||||||
(capinfo & IEEE80211_CAPINFO_PRIVACY) !=
|
(capinfo & IEEE80211_CAPINFO_PRIVACY) !=
|
||||||
((ic->ic_flags & IEEE80211_F_WEPON) ?
|
((ic->ic_flags & IEEE80211_F_WEPON) ?
|
||||||
IEEE80211_CAPINFO_PRIVACY : 0)) {
|
IEEE80211_CAPINFO_PRIVACY : 0)) {
|
||||||
|
bs->bs_associd = 0;
|
||||||
IEEE80211_SEND_MGMT(ic, bs, resp, IEEE80211_STATUS_CAPINFO);
|
IEEE80211_SEND_MGMT(ic, bs, resp, IEEE80211_STATUS_CAPINFO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1729,6 +1838,7 @@ ieee80211_recv_asreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
ieee80211_fix_rate(ic, bs, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
|
ieee80211_fix_rate(ic, bs, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
|
||||||
IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
|
IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
|
||||||
if (bs->bs_nrate == 0) {
|
if (bs->bs_nrate == 0) {
|
||||||
|
bs->bs_associd = 0;
|
||||||
IEEE80211_SEND_MGMT(ic, bs, resp, IEEE80211_STATUS_BASIC_RATE);
|
IEEE80211_SEND_MGMT(ic, bs, resp, IEEE80211_STATUS_BASIC_RATE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1739,8 +1849,16 @@ ieee80211_recv_asreq(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
bs->bs_chan = ic->ic_bss.bs_chan;
|
bs->bs_chan = ic->ic_bss.bs_chan;
|
||||||
bs->bs_fhdwell = ic->ic_bss.bs_fhdwell;
|
bs->bs_fhdwell = ic->ic_bss.bs_fhdwell;
|
||||||
bs->bs_fhindex = ic->ic_bss.bs_fhindex;
|
bs->bs_fhindex = ic->ic_bss.bs_fhindex;
|
||||||
bs->bs_associd = 0xc000 | ic->ic_bss.bs_associd++;
|
if (bs->bs_associd == 0) {
|
||||||
|
bs->bs_associd = 0xc000 | ic->ic_bss.bs_associd++;
|
||||||
|
newassoc = 1;
|
||||||
|
} else
|
||||||
|
newassoc = 0;
|
||||||
IEEE80211_SEND_MGMT(ic, bs, resp, IEEE80211_STATUS_SUCCESS);
|
IEEE80211_SEND_MGMT(ic, bs, resp, IEEE80211_STATUS_SUCCESS);
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s %s associated\n",
|
||||||
|
ifp->if_xname, (newassoc ? "newly" : "already"),
|
||||||
|
ether_sprintf(bs->bs_macaddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1753,6 +1871,11 @@ ieee80211_recv_asresp(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
u_int8_t *frm, *efrm, *rates;
|
u_int8_t *frm, *efrm, *rates;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
if ((ic->ic_flags & IEEE80211_F_HOSTAP) ||
|
||||||
|
(ic->ic_flags & IEEE80211_F_ADHOC) ||
|
||||||
|
ic->ic_state != IEEE80211_S_ASSOC)
|
||||||
|
return;
|
||||||
|
|
||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
frm = (u_int8_t *)&wh[1];
|
frm = (u_int8_t *)&wh[1];
|
||||||
efrm = mtod(m0, u_int8_t *) + m0->m_len;
|
efrm = mtod(m0, u_int8_t *) + m0->m_len;
|
||||||
|
@ -1805,10 +1928,40 @@ static void
|
||||||
ieee80211_recv_disassoc(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
ieee80211_recv_disassoc(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
u_int32_t rstamp)
|
u_int32_t rstamp)
|
||||||
{
|
{
|
||||||
|
struct ifnet *ifp = &ic->ic_if;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
|
struct ieee80211_bss *bs;
|
||||||
|
u_int8_t *frm, *efrm;
|
||||||
|
u_int16_t reason;
|
||||||
|
|
||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0)
|
frm = (u_int8_t *)&wh[1];
|
||||||
|
efrm = mtod(m0, u_int8_t *) + m0->m_len;
|
||||||
|
/*
|
||||||
|
* disassoc frame format
|
||||||
|
* [2] reason
|
||||||
|
*/
|
||||||
|
if (frm + 2 > efrm) {
|
||||||
|
DPRINTF(("ieee80211_recv_disassoc: too short from %s\n",
|
||||||
|
ether_sprintf(wh->i_addr2)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reason = le16toh(*(u_int16_t *)frm);
|
||||||
|
if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
||||||
|
TAILQ_FOREACH(bs, &ic->ic_scan, bs_list) {
|
||||||
|
if (memcmp(wh->i_addr2, bs->bs_macaddr,
|
||||||
|
IEEE80211_ADDR_LEN) == 0) {
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s disassociated"
|
||||||
|
" by peer (reason %d)\n",
|
||||||
|
ifp->if_xname,
|
||||||
|
ether_sprintf(bs->bs_macaddr),
|
||||||
|
reason);
|
||||||
|
bs->bs_associd = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0)
|
||||||
ieee80211_new_state(&ic->ic_if, IEEE80211_S_ASSOC,
|
ieee80211_new_state(&ic->ic_if, IEEE80211_S_ASSOC,
|
||||||
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
|
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
|
||||||
}
|
}
|
||||||
|
@ -1817,10 +1970,43 @@ static void
|
||||||
ieee80211_recv_deauth(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
ieee80211_recv_deauth(struct ieee80211com *ic, struct mbuf *m0, int rssi,
|
||||||
u_int32_t rstamp)
|
u_int32_t rstamp)
|
||||||
{
|
{
|
||||||
|
struct ifnet *ifp = &ic->ic_if;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
|
struct ieee80211_bss *bs;
|
||||||
|
u_int8_t *frm, *efrm;
|
||||||
|
u_int16_t reason;
|
||||||
|
|
||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0)
|
frm = (u_int8_t *)&wh[1];
|
||||||
|
efrm = mtod(m0, u_int8_t *) + m0->m_len;
|
||||||
|
/*
|
||||||
|
* dauth frame format
|
||||||
|
* [2] reason
|
||||||
|
*/
|
||||||
|
if (frm + 2 > efrm) {
|
||||||
|
DPRINTF(("ieee80211_recv_deauth: too short from %s\n",
|
||||||
|
ether_sprintf(wh->i_addr2)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reason = le16toh(*(u_int16_t *)frm);
|
||||||
|
if (ic->ic_flags & IEEE80211_F_HOSTAP) {
|
||||||
|
TAILQ_FOREACH(bs, &ic->ic_scan, bs_list) {
|
||||||
|
if (memcmp(wh->i_addr2, bs->bs_macaddr,
|
||||||
|
IEEE80211_ADDR_LEN) == 0) {
|
||||||
|
if (ifp->if_flags & IFF_DEBUG)
|
||||||
|
printf("%s: station %s deauthenticated"
|
||||||
|
" by peer (reason %d)\n",
|
||||||
|
ifp->if_xname,
|
||||||
|
ether_sprintf(bs->bs_macaddr),
|
||||||
|
reason);
|
||||||
|
TAILQ_REMOVE(&ic->ic_scan, bs, bs_list);
|
||||||
|
free(bs, M_DEVBUF);
|
||||||
|
if (TAILQ_EMPTY(&ic->ic_scan))
|
||||||
|
ic->ic_inact_timer = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0)
|
||||||
ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH,
|
ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH,
|
||||||
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
|
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
|
||||||
}
|
}
|
||||||
|
@ -2024,8 +2210,13 @@ ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt)
|
||||||
case IEEE80211_S_SCAN: /* adhoc mode */
|
case IEEE80211_S_SCAN: /* adhoc mode */
|
||||||
case IEEE80211_S_ASSOC: /* infra mode */
|
case IEEE80211_S_ASSOC: /* infra mode */
|
||||||
if (ifp->if_flags & IFF_DEBUG) {
|
if (ifp->if_flags & IFF_DEBUG) {
|
||||||
printf("%s: associated with %s ssid ",
|
printf("%s: ", ifp->if_xname);
|
||||||
ifp->if_xname,
|
if ((ic->ic_flags & IEEE80211_F_ADHOC) ||
|
||||||
|
(ic->ic_flags & IEEE80211_F_HOSTAP))
|
||||||
|
printf("synchronized ");
|
||||||
|
else
|
||||||
|
printf("associated ");
|
||||||
|
printf("with %s ssid ",
|
||||||
ether_sprintf(ic->ic_bss.bs_bssid));
|
ether_sprintf(ic->ic_bss.bs_bssid));
|
||||||
ieee80211_print_essid(ic->ic_bss.bs_essid,
|
ieee80211_print_essid(ic->ic_bss.bs_essid,
|
||||||
ic->ic_bss.bs_esslen);
|
ic->ic_bss.bs_esslen);
|
||||||
|
@ -2187,10 +2378,13 @@ ieee80211_wep_crypt(struct ifnet *ifp, struct mbuf *m0, int txflag)
|
||||||
}
|
}
|
||||||
if (crc != le32toh(*(u_int32_t *)crcbuf)) {
|
if (crc != le32toh(*(u_int32_t *)crcbuf)) {
|
||||||
#ifdef IEEE80211_DEBUG
|
#ifdef IEEE80211_DEBUG
|
||||||
printf("ieee80211_wep_crypt: decrypt CRC error\n");
|
if (ieee80211_debug) {
|
||||||
if (ieee80211_debug)
|
printf("%s: decrypt CRC error\n",
|
||||||
ieee80211_dump_pkt(n0->m_data, n0->m_len,
|
ifp->if_xname);
|
||||||
-1, -1);
|
if (ieee80211_debug > 1)
|
||||||
|
ieee80211_dump_pkt(n0->m_data,
|
||||||
|
n0->m_len, -1, -1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue