Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Fix a bug in ieee80211_compute_duration: the 802.11 Dura...
details: https://anonhg.NetBSD.org/src/rev/238cf9c2faf2
branches: trunk
changeset: 572191:238cf9c2faf2
user: dyoung <dyoung%NetBSD.org@localhost>
date: Thu Dec 23 06:08:52 2004 +0000
description:
Fix a bug in ieee80211_compute_duration: the 802.11 Duration field
in an 802.11 unicast data packet is equal to the duration of the
SIFS and Acknowledgement. That is, the amount of time reserved
*after* the packet has finished transmitting.
Change the arguments to ieee80211_compute_duration: pass the entire
packet length, not just the payload length. Add a 'debug' argument
to ieee80211_compute_duration and its helper subroutine,
ieee80211_compute_duration1.
If debug != 0, ieee80211_compute_duration printfs its arguments
and several local variables.
In rtw(4), load the 802.11 Duration field with the result from
ieee80211_compute_duration.
diffstat:
sys/dev/ic/rtw.c | 11 +++++----
sys/net80211/ieee80211_output.c | 46 ++++++++++++++++++++++++----------------
sys/net80211/ieee80211_proto.h | 4 +-
3 files changed, 36 insertions(+), 25 deletions(-)
diffs (152 lines):
diff -r ac0ac78ff6f2 -r 238cf9c2faf2 sys/dev/ic/rtw.c
--- a/sys/dev/ic/rtw.c Thu Dec 23 06:03:09 2004 +0000
+++ b/sys/dev/ic/rtw.c Thu Dec 23 06:08:52 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtw.c,v 1.18 2004/12/23 06:03:09 dyoung Exp $ */
+/* $NetBSD: rtw.c,v 1.19 2004/12/23 06:08:52 dyoung Exp $ */
/*-
* Copyright (c) 2004, 2005 David Young. All rights reserved.
*
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.18 2004/12/23 06:03:09 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.19 2004/12/23 06:08:52 dyoung Exp $");
#include "bpfilter.h"
@@ -2530,10 +2530,11 @@
wh = mtod(m0, struct ieee80211_frame *);
- if (ieee80211_compute_duration(wh,
- m0->m_pkthdr.len - sizeof(wh),
+ if (ieee80211_compute_duration(wh, m0->m_pkthdr.len,
ic->ic_flags, ic->ic_fragthreshold,
- rate, &stx->stx_d0, &stx->stx_dn, &npkt) == -1) {
+ rate, &stx->stx_d0, &stx->stx_dn, &npkt,
+ (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
+ (IFF_DEBUG|IFF_LINK2)) == -1) {
DPRINTF2(sc, ("%s: fail compute duration\n", __func__));
goto post_load_err;
}
diff -r ac0ac78ff6f2 -r 238cf9c2faf2 sys/net80211/ieee80211_output.c
--- a/sys/net80211/ieee80211_output.c Thu Dec 23 06:03:09 2004 +0000
+++ b/sys/net80211/ieee80211_output.c Thu Dec 23 06:08:52 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_output.c,v 1.18 2004/12/19 08:08:06 dyoung Exp $ */
+/* $NetBSD: ieee80211_output.c,v 1.19 2004/12/23 06:08:52 dyoung Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -35,7 +35,7 @@
#ifdef __FreeBSD__
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.10 2004/04/02 23:25:39 sam Exp $");
#else
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_output.c,v 1.18 2004/12/19 08:08:06 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_output.c,v 1.19 2004/12/23 06:08:52 dyoung Exp $");
#endif
#include "opt_inet.h"
@@ -343,26 +343,27 @@
return -1;
}
+ d->d_plcp_len = data_dur;
+
d->d_rts_dur = data_dur + 3 * (IEEE80211_DUR_DS_SIFS +
IEEE80211_DUR_DS_SHORT_PREAMBLE +
IEEE80211_DUR_DS_FAST_PLCPHDR) + cts + ack;
- d->d_data_dur = data_dur + IEEE80211_DUR_DS_SIFS +
- 2 * (IEEE80211_DUR_DS_SHORT_PREAMBLE +
- IEEE80211_DUR_DS_FAST_PLCPHDR) + ack;
- d->d_plcp_len = data_dur;
+ /* Note that this is the amount of time reserved *after*
+ * the packet is transmitted: just long enough for a SIFS
+ * and an ACK.
+ */
+ d->d_data_dur = IEEE80211_DUR_DS_SIFS +
+ IEEE80211_DUR_DS_SHORT_PREAMBLE + IEEE80211_DUR_DS_FAST_PLCPHDR +
+ ack;
if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
return 0;
- d->d_rts_dur += 3 * (IEEE80211_DUR_DS_LONG_PREAMBLE -
- IEEE80211_DUR_DS_SHORT_PREAMBLE) +
- 3 * (IEEE80211_DUR_DS_SLOW_PLCPHDR -
- IEEE80211_DUR_DS_FAST_PLCPHDR);
- d->d_data_dur += 2 * (IEEE80211_DUR_DS_LONG_PREAMBLE -
- IEEE80211_DUR_DS_SHORT_PREAMBLE) +
- 2 * (IEEE80211_DUR_DS_SLOW_PLCPHDR -
- IEEE80211_DUR_DS_FAST_PLCPHDR);
+ d->d_rts_dur += 3 * IEEE80211_DUR_DS_PREAMBLE_DIFFERENCE +
+ 3 * IEEE80211_DUR_DS_PLCPHDR_DIFFERENCE;
+ d->d_data_dur += IEEE80211_DUR_DS_PREAMBLE_DIFFERENCE +
+ IEEE80211_DUR_DS_PLCPHDR_DIFFERENCE;
return 0;
}
@@ -391,18 +392,20 @@
* of first/only fragment
*/
int
-ieee80211_compute_duration(struct ieee80211_frame *wh, int paylen,
+ieee80211_compute_duration(struct ieee80211_frame *wh, int len,
uint32_t flags, int fraglen, int rate, struct ieee80211_duration *d0,
- struct ieee80211_duration *dn, int *npktp)
+ struct ieee80211_duration *dn, int *npktp, int debug)
{
int rc;
- int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen;
+ int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
hdrlen = sizeof(struct ieee80211_frame_addr4);
else
hdrlen = sizeof(struct ieee80211_frame);
+ paylen = len - hdrlen;
+
if ((flags & IEEE80211_F_PRIVACY) != 0) {
overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
#if 0 /* 802.11 lets us extend a fragment's length by the length of
@@ -438,10 +441,17 @@
else
firstlen = paylen + overlen;
+ if (debug) {
+ printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
+ "fraglen %d overlen %d len %d rate %d flags %08x\n",
+ __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
+ overlen, len, rate, flags);
+ }
rc = ieee80211_compute_duration1(firstlen + hdrlen, flags, rate, d0);
if (rc == -1)
return rc;
- if (npkt > 1) {
+
+ if (npkt <= 1) {
*dn = *d0;
return 0;
}
diff -r ac0ac78ff6f2 -r 238cf9c2faf2 sys/net80211/ieee80211_proto.h
--- a/sys/net80211/ieee80211_proto.h Thu Dec 23 06:03:09 2004 +0000
+++ b/sys/net80211/ieee80211_proto.h Thu Dec 23 06:08:52 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_proto.h,v 1.6 2004/12/19 08:08:06 dyoung Exp $ */
+/* $NetBSD: ieee80211_proto.h,v 1.7 2004/12/23 06:08:52 dyoung Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -80,7 +80,7 @@
struct ieee80211_node *, u_int64_t);
extern int ieee80211_compute_duration(struct ieee80211_frame *, int,
uint32_t, int, int, struct ieee80211_duration *,
- struct ieee80211_duration *, int *);
+ struct ieee80211_duration *, int *, int);
extern const char *ieee80211_state_name[IEEE80211_S_MAX];
#endif /* _NET80211_IEEE80211_PROTO_H_ */
Home |
Main Index |
Thread Index |
Old Index