All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benoit PAPILLAULT <benoit.papillault@free.fr>
To: ath9k-devel@lists.ath9k.org
Subject: [ath9k-devel] [PATCH] ath9k: This patch fix RX unpadding for any received frame.
Date: Fri, 20 Nov 2009 22:22:43 +0100	[thread overview]
Message-ID: <4B0708A3.3060209@free.fr> (raw)
In-Reply-To: <43e72e890911200917m47ad6a8aje23577bf734b4952@mail.gmail.com>

Luis R. Rodriguez a ?crit :
> On Thu, Nov 19, 2009 at 1:19 PM, Benoit Papillault
> <benoit.papillault@free.fr> wrote:
>> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>>
>> It has been tested with a 802.11 frame generator and by checking the FCS field
>> of each received frame with the value reported by the Atheros hardware. This
>> patch is useful if you are trying to analyze non standard 802.11 frame going
>> over the air.
> 
> Thank you for your patch! But can you please elaborate on your commit
> log entry? This just tells me that you've tested it and how its useful
> but it in no way tells me what you found was wrong and also does not
> explain how you fixed it.

Sure. I use a 802.11 frame generator that generates every value for the
first 2 bytes (frame control field) and a varying length. What was wrong
is that using ath9k and a monitor interface, I was getting frames with
padding still inside or unpadding done at the wrong position and as
such, wrong FCS. In order to fix it, I use the FCS field of received
frame and tried every position and size for unpadding. This way I found
a formula that gives me the exact position and size for proper
unpadding. I then put this formula into ath9k. This formula is different
from 802.11 hdrlen.

> 
>> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>> ---
>>  drivers/net/wireless/ath/ath9k/common.c |   19 ++++++++++++++-----
>>  1 files changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
>> index 2f1e161..4a13632 100644
>> --- a/drivers/net/wireless/ath/ath9k/common.c
>> +++ b/drivers/net/wireless/ath/ath9k/common.c
>> @@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
>>  {
>>        struct ath_hw *ah = common->ah;
>>        struct ieee80211_hdr *hdr;
>> -       int hdrlen, padsize;
>> +       int hdrlen, padpos, padsize;
>>        u8 keyix;
>>        __le16 fc;
>>
>>        /* see if any padding is done by the hw and remove it */
>>        hdr = (struct ieee80211_hdr *) skb->data;
>>        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
>> +       padpos = 24;
>>        fc = hdr->frame_control;
>> +       if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
>> +           cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
>> +         padpos += 6; /* ETH_ALEN */
>> +       }
> 
> How about just using ETH_ALEN then?

Indeed. I was just in a hurry.

> 
>> +       if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
>> +           cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
>> +         padpos += 2;
>> +       }
>>
>>        /* The MAC header is padded to have 32-bit boundary if the
>>         * packet payload is non-zero. The general calculation for
>>         * padsize would take into account odd header lengths:
>> -        * padsize = (4 - hdrlen % 4) % 4; However, since only
>> +        * padsize = (4 - padpos % 4) % 4; However, since only
>>         * even-length headers are used, padding can only be 0 or 2
>>         * bytes and we can optimize this a bit. In addition, we must
>>         * not try to remove padding from short control frames that do
>>         * not have payload. */
>> -       padsize = hdrlen & 3;
>> -       if (padsize && hdrlen >= 24) {
>> -               memmove(skb->data + padsize, skb->data, hdrlen);
>> +       padsize = padpos & 3;
>> +       if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
>> +               memmove(skb->data + padsize, skb->data, padpos);
>>                skb_pull(skb, padsize);
>>        }
> 
> If the skb->len would have been short ieee80211_get_hdrlen_from_skb()
> would have picked up on this and 0 would have been used for hdrlen
> therefore skipping this operation. With this patch even if skb->len
> was 0 your padsize is always based on some static value. Additionally
> its unclear to me how and why you substitute
> ieee80211_get_hdrlen_from_skb() to a static 24 + something.

The substitution is indeed the key of this patch. The check about
skb->len is to make sure that the frame is large enough to contain the
computed padding, which cannot be contained in the FCS field itself.

> 
> Also the possible static values for padpos are either (24 + 2) or (24
> + 6) right? Well these & 3 will always give true. So you are always
> padding and this changes the way this was being implemented.

It can be 24, 24+6=30, 24+2=26 or 24+6+2=28. With the &3 mask, this
gives : 0 (for 24), 2 (for 30), 2 (for 26) and 0 (for 28).

> 
> Unless I'm missing something.
> 
>   Luis
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

Regards,
Benoit

WARNING: multiple messages have this Message-ID (diff)
From: Benoit PAPILLAULT <benoit.papillault@free.fr>
To: "Luis R. Rodriguez" <lrodriguez@atheros.com>
Cc: jmalinen@atheros.com, linux-wireless@vger.kernel.org,
	ath9k-devel@lists.ath9k.org
Subject: Re: [PATCH] ath9k: This patch fix RX unpadding for any received frame.
Date: Fri, 20 Nov 2009 22:22:43 +0100	[thread overview]
Message-ID: <4B0708A3.3060209@free.fr> (raw)
In-Reply-To: <43e72e890911200917m47ad6a8aje23577bf734b4952@mail.gmail.com>

Luis R. Rodriguez a écrit :
> On Thu, Nov 19, 2009 at 1:19 PM, Benoit Papillault
> <benoit.papillault@free.fr> wrote:
>> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>>
>> It has been tested with a 802.11 frame generator and by checking the FCS field
>> of each received frame with the value reported by the Atheros hardware. This
>> patch is useful if you are trying to analyze non standard 802.11 frame going
>> over the air.
> 
> Thank you for your patch! But can you please elaborate on your commit
> log entry? This just tells me that you've tested it and how its useful
> but it in no way tells me what you found was wrong and also does not
> explain how you fixed it.

Sure. I use a 802.11 frame generator that generates every value for the
first 2 bytes (frame control field) and a varying length. What was wrong
is that using ath9k and a monitor interface, I was getting frames with
padding still inside or unpadding done at the wrong position and as
such, wrong FCS. In order to fix it, I use the FCS field of received
frame and tried every position and size for unpadding. This way I found
a formula that gives me the exact position and size for proper
unpadding. I then put this formula into ath9k. This formula is different
from 802.11 hdrlen.

> 
>> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>> ---
>>  drivers/net/wireless/ath/ath9k/common.c |   19 ++++++++++++++-----
>>  1 files changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
>> index 2f1e161..4a13632 100644
>> --- a/drivers/net/wireless/ath/ath9k/common.c
>> +++ b/drivers/net/wireless/ath/ath9k/common.c
>> @@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
>>  {
>>        struct ath_hw *ah = common->ah;
>>        struct ieee80211_hdr *hdr;
>> -       int hdrlen, padsize;
>> +       int hdrlen, padpos, padsize;
>>        u8 keyix;
>>        __le16 fc;
>>
>>        /* see if any padding is done by the hw and remove it */
>>        hdr = (struct ieee80211_hdr *) skb->data;
>>        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
>> +       padpos = 24;
>>        fc = hdr->frame_control;
>> +       if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
>> +           cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
>> +         padpos += 6; /* ETH_ALEN */
>> +       }
> 
> How about just using ETH_ALEN then?

Indeed. I was just in a hurry.

> 
>> +       if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
>> +           cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
>> +         padpos += 2;
>> +       }
>>
>>        /* The MAC header is padded to have 32-bit boundary if the
>>         * packet payload is non-zero. The general calculation for
>>         * padsize would take into account odd header lengths:
>> -        * padsize = (4 - hdrlen % 4) % 4; However, since only
>> +        * padsize = (4 - padpos % 4) % 4; However, since only
>>         * even-length headers are used, padding can only be 0 or 2
>>         * bytes and we can optimize this a bit. In addition, we must
>>         * not try to remove padding from short control frames that do
>>         * not have payload. */
>> -       padsize = hdrlen & 3;
>> -       if (padsize && hdrlen >= 24) {
>> -               memmove(skb->data + padsize, skb->data, hdrlen);
>> +       padsize = padpos & 3;
>> +       if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
>> +               memmove(skb->data + padsize, skb->data, padpos);
>>                skb_pull(skb, padsize);
>>        }
> 
> If the skb->len would have been short ieee80211_get_hdrlen_from_skb()
> would have picked up on this and 0 would have been used for hdrlen
> therefore skipping this operation. With this patch even if skb->len
> was 0 your padsize is always based on some static value. Additionally
> its unclear to me how and why you substitute
> ieee80211_get_hdrlen_from_skb() to a static 24 + something.

The substitution is indeed the key of this patch. The check about
skb->len is to make sure that the frame is large enough to contain the
computed padding, which cannot be contained in the FCS field itself.

> 
> Also the possible static values for padpos are either (24 + 2) or (24
> + 6) right? Well these & 3 will always give true. So you are always
> padding and this changes the way this was being implemented.

It can be 24, 24+6=30, 24+2=26 or 24+6+2=28. With the &3 mask, this
gives : 0 (for 24), 2 (for 30), 2 (for 26) and 0 (for 28).

> 
> Unless I'm missing something.
> 
>   Luis
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

Regards,
Benoit

  reply	other threads:[~2009-11-20 21:22 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-19 21:19 [ath9k-devel] [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit Papillault
2009-11-19 21:19 ` Benoit Papillault
2009-11-19 21:25 ` [ath9k-devel] " John W. Linville
2009-11-19 21:25   ` John W. Linville
2009-11-19 21:36   ` [ath9k-devel] " Benoit PAPILLAULT
2009-11-19 21:36     ` Benoit PAPILLAULT
2009-11-20 17:17 ` [ath9k-devel] " Luis R. Rodriguez
2009-11-20 17:17   ` Luis R. Rodriguez
2009-11-20 21:22   ` Benoit PAPILLAULT [this message]
2009-11-20 21:22     ` Benoit PAPILLAULT
  -- strict thread matches above, loose matches on Subject: below --
2009-11-24 14:49 [ath9k-devel] " Benoit Papillault
2009-11-24 14:51 ` Benoit PAPILLAULT

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B0708A3.3060209@free.fr \
    --to=benoit.papillault@free.fr \
    --cc=ath9k-devel@lists.ath9k.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.