diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index b52c044e6985..2e8995ca4261 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: ieee80211_input.c,v 1.49 2005/11/19 21:09:17 he Exp $ */ +/* $NetBSD: ieee80211_input.c,v 1.50 2005/11/20 10:04:21 dyoung Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting @@ -36,7 +36,7 @@ __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $"); #endif #ifdef __NetBSD__ -__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.49 2005/11/19 21:09:17 he Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.50 2005/11/20 10:04:21 dyoung Exp $"); #endif #include "opt_inet.h" @@ -262,7 +262,8 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m, * exist. This should probably done after an ACL check. */ if (ni == ic->ic_bss && - ic->ic_opmode != IEEE80211_M_HOSTAP) { + ic->ic_opmode != IEEE80211_M_HOSTAP && + !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { /* * Fake up a node for this newly * discovered member of the IBSS. @@ -2035,6 +2036,12 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, * Create a new entry in the neighbor table. */ ni = ieee80211_add_neighbor(ic, wh, &scan); + } else if (ni->ni_capinfo == 0) { + /* + * Initialize a node that was "faked + * up." This updates the TSF, too. + */ + ieee80211_init_neighbor(ic, ni, wh, &scan, 0); } else { /* * Record tsf for potential resync. @@ -2096,7 +2103,11 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, } if (ni == ic->ic_bss) { - if (ic->ic_opmode == IEEE80211_M_IBSS) { + if (ic->ic_opmode != IEEE80211_M_IBSS) + ni = ieee80211_tmp_node(ic, wh->i_addr2); + else if (IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) + ; + else { /* * XXX Cannot tell if the sender is operating * in ibss mode. But we need a new node to @@ -2105,8 +2116,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, */ ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, wh->i_addr2); - } else - ni = ieee80211_tmp_node(ic, wh->i_addr2); + } if (ni == NULL) return; allocbs = 1; diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index d06f957d4c7d..ce60cee4b091 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $NetBSD: ieee80211_node.c,v 1.45 2005/11/18 16:40:09 skrll Exp $ */ +/* $NetBSD: ieee80211_node.c,v 1.46 2005/11/20 10:04:21 dyoung Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting @@ -36,7 +36,7 @@ __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.65 2005/08/13 17:50:21 sam Exp $"); #endif #ifdef __NetBSD__ -__KERNEL_RCSID(0, "$NetBSD: ieee80211_node.c,v 1.45 2005/11/18 16:40:09 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ieee80211_node.c,v 1.46 2005/11/20 10:04:21 dyoung Exp $"); #endif #include "opt_inet.h" @@ -1259,6 +1259,35 @@ ieee80211_add_scan(struct ieee80211com *ic, #undef ISPROBE } +void +ieee80211_init_neighbor(struct ieee80211com *ic, struct ieee80211_node *ni, + const struct ieee80211_frame *wh, const struct ieee80211_scanparams *sp, + int isnew) +{ + ni->ni_esslen = sp->ssid[1]; + memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); + IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); + memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp)); + ni->ni_intval = sp->bintval; + ni->ni_capinfo = sp->capinfo; + ni->ni_chan = ic->ic_bss->ni_chan; + ni->ni_fhdwell = sp->fhdwell; + ni->ni_fhindex = sp->fhindex; + ni->ni_erp = sp->erp; + ni->ni_timoff = sp->timoff; + if (sp->wme != NULL) + ieee80211_saveie(&ni->ni_wme_ie, sp->wme); + if (sp->wpa != NULL) + ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa); + + /* NB: must be after ni_chan is setup */ + ieee80211_setup_rates(ni, sp->rates, sp->xrates, + IEEE80211_F_DONEGO | IEEE80211_F_DOSORT); + + if (ic->ic_newassoc != NULL) + ic->ic_newassoc(ni, isnew); +} + /* * Do node discovery in adhoc mode on receipt of a beacon * or probe response frame. Note that for the driver's @@ -1274,27 +1303,7 @@ ieee80211_add_neighbor(struct ieee80211com *ic, ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);/* XXX alloc_node? */ if (ni != NULL) { - ni->ni_esslen = sp->ssid[1]; - memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); - IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); - memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp)); - ni->ni_intval = sp->bintval; - ni->ni_capinfo = sp->capinfo; - ni->ni_chan = ic->ic_bss->ni_chan; - ni->ni_fhdwell = sp->fhdwell; - ni->ni_fhindex = sp->fhindex; - ni->ni_erp = sp->erp; - ni->ni_timoff = sp->timoff; - if (sp->wme != NULL) - ieee80211_saveie(&ni->ni_wme_ie, sp->wme); - if (sp->wpa != NULL) - ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa); - - /* NB: must be after ni_chan is setup */ - ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT); - - if (ic->ic_newassoc != NULL) - ic->ic_newassoc(ni, 1); + ieee80211_init_neighbor(ic, ni, wh, sp, 1); /* XXX not right for 802.1x/WPA */ ieee80211_node_authorize(ni); } diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 6cb297833eeb..8ed1e845da00 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -1,4 +1,4 @@ -/* $NetBSD: ieee80211_node.h,v 1.19 2005/11/18 16:40:09 skrll Exp $ */ +/* $NetBSD: ieee80211_node.h,v 1.20 2005/11/20 10:04:21 dyoung Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting @@ -331,6 +331,9 @@ void ieee80211_add_scan(struct ieee80211com *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, int subtype, int rssi, int rstamp); +void ieee80211_init_neighbor(struct ieee80211com *, struct ieee80211_node *, + const struct ieee80211_frame *, + const struct ieee80211_scanparams *, int); struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211com *, const struct ieee80211_frame *, const struct ieee80211_scanparams *);