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.
This commit is contained in:
parent
ce08175fd3
commit
24ba04b962
|
@ -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 @@ rtw_start(struct ifnet *ifp)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 @@ ieee80211_compute_duration1(int len, uint32_t flags, int rate,
|
|||
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 @@ ieee80211_compute_duration1(int len, uint32_t flags, int rate,
|
|||
* 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 @@ ieee80211_compute_duration(struct ieee80211_frame *wh, int paylen,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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 @@ extern int ieee80211_ibss_merge(struct ieee80211com *,
|
|||
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_ */
|
||||
|
|
Loading…
Reference in New Issue