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