Project : madwifi
Revision : 2633
Author : mentor (Matthew W. S. Bell)
Date : 2007-08-04 03:54:59 +0200 (Sat, 04 Aug 2007)
Log Message :
Stop a socket buffer leak when switching to a channel that doesn't exist.
This patch stops the leak, and also does an initial check.
The API for calling for a channel switch should probably be made better.
Signed-off-by: Andrew Lunn <andrew@xxxxxxx>. Edited by me.
Affected Files:
* trunk/net80211/ieee80211_beacon.c updated
Modified: trunk/net80211/ieee80211_beacon.c
===================================================================
--- trunk/net80211/ieee80211_beacon.c 2007-08-03 09:03:35 UTC (rev 2632)
+++ trunk/net80211/ieee80211_beacon.c 2007-08-04 01:54:59 UTC (rev 2633)
@@ -289,45 +289,48 @@
IEEE80211_LOCK_IRQ(ic);
if ((ic->ic_flags & IEEE80211_F_DOTH) &&
- (vap->iv_flags & IEEE80211_F_CHANSWITCH) &&
- (vap->iv_chanchange_count == ic->ic_chanchange_tbtt)) {
- u_int8_t *frm;
- struct ieee80211_channel *c;
+ (vap->iv_flags & IEEE80211_F_CHANSWITCH)) {
+ struct ieee80211_channel *c =
+ ieee80211_doth_findchan(vap, ic->ic_chanchange_chan);
+
+ if (!vap->iv_chanchange_count && !c) {
+ vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
+ ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
+ } else if (vap->iv_chanchange_count == ic->ic_chanchange_tbtt) {
+ u_int8_t *frm;
- vap->iv_chanchange_count = 0;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
+ "%s: reinit beacon\n", __func__);
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
- "%s: reinit beacon\n", __func__);
+ /* NB: ic_bsschan is in the DSPARMS beacon IE, so must
set this
+ * prior to the beacon re-init, below. */
+ if (c == NULL) {
+ /* Requested channel invalid; drop the channel
switch
+ * announcement and do nothing. */
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
+ "%s: find channel failure\n",
__func__);
+ } else
+ ic->ic_bsschan = c;
- /*
- * NB: ic_bsschan is in the DSPARMS beacon IE, so must set this
- * prior to the beacon re-init, below.
- */
- c = ieee80211_doth_findchan(vap, ic->ic_chanchange_chan);
- if (c == NULL) {
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
- "%s: find channel failure\n", __func__);
- IEEE80211_UNLOCK_IRQ_EARLY(ic);
- return 0;
- }
- ic->ic_bsschan = c;
+ skb_pull(skb, sizeof(struct ieee80211_frame));
+ skb_trim(skb, 0);
+ frm = skb->data;
+ skb_put(skb, ieee80211_beacon_init(ni, bo, frm) - frm);
+ skb_push(skb, sizeof(struct ieee80211_frame));
- skb_pull(skb, sizeof(struct ieee80211_frame));
- skb_trim(skb, 0);
- frm = skb->data;
- skb_put(skb, ieee80211_beacon_init(ni, bo, frm) - frm);
- skb_push(skb, sizeof(struct ieee80211_frame));
+ vap->iv_chanchange_count = 0;
+ vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
+ ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
- vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
- ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
+ /* NB: Only for the first VAP to get here, and when we
have a
+ * valid channel to which to change. */
+ if (c && (ic->ic_curchan != c)) {
+ ic->ic_curchan = c;
+ ic->ic_set_channel(ic);
+ }
- /* NB: only for the first VAP to get here */
- if (ic->ic_curchan != c) {
- ic->ic_curchan = c;
- ic->ic_set_channel(ic);
+ len_changed = 1;
}
-
- len_changed = 1;
}
/* XXX faster to recalculate entirely or just changes? */
@@ -335,6 +338,7 @@
capinfo = IEEE80211_CAPINFO_IBSS;
else
capinfo = IEEE80211_CAPINFO_ESS;
+
if (vap->iv_flags & IEEE80211_F_PRIVACY)
capinfo |= IEEE80211_CAPINFO_PRIVACY;
if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
@@ -497,9 +501,9 @@
/* indicate new beacon length so other layers
may manage memory */
skb_put(skb, IEEE80211_CHANSWITCHANN_BYTES);
len_changed = 1;
- }
- else
+ } else
bo->bo_chanswitch[4]--;
+
vap->iv_chanchange_count++;
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
"%s: CHANSWITCH IE, change in %d\n",
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
|