aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTony Cheneau <tony.cheneau@amnesiak.org>2012-07-11 02:51:16 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-17 01:52:02 -0400
commit5e96855fc505082389813afcf796d4c46301d4fe (patch)
tree8f92e75d5336d2b64a2359f50154c0752fb60fd3 /net
parent4576039ffc04ffe672081159a11cf6e0b875a069 (diff)
6lowpan: Change byte order when storing/accessing to len field
Lenght field should be encoded using big endian byte order, such as intend in the specs. As it is currently written, the len field would not be decoded properly on an implementation using the correct byte ordering. Hence, it could lead to interroperability issues. Also, I rewrote the code so that iphc0 argument of lowpan_alloc_new_frame could be removed. Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ieee802154/6lowpan.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 536c6e21b20e..6a095225148e 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -645,7 +645,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr)
645} 645}
646 646
647static struct lowpan_fragment * 647static struct lowpan_fragment *
648lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u16 tag) 648lowpan_alloc_new_frame(struct sk_buff *skb, u8 len, u16 tag)
649{ 649{
650 struct lowpan_fragment *frame; 650 struct lowpan_fragment *frame;
651 651
@@ -656,7 +656,7 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u16 tag)
656 656
657 INIT_LIST_HEAD(&frame->list); 657 INIT_LIST_HEAD(&frame->list);
658 658
659 frame->length = (iphc0 & 7) | (len << 3); 659 frame->length = len;
660 frame->tag = tag; 660 frame->tag = tag;
661 661
662 /* allocate buffer for frame assembling */ 662 /* allocate buffer for frame assembling */
@@ -714,14 +714,18 @@ lowpan_process_data(struct sk_buff *skb)
714 case LOWPAN_DISPATCH_FRAGN: 714 case LOWPAN_DISPATCH_FRAGN:
715 { 715 {
716 struct lowpan_fragment *frame; 716 struct lowpan_fragment *frame;
717 u8 len, offset; 717 /* slen stores the rightmost 8 bits of the 11 bits length */
718 u16 tag; 718 u8 slen, offset;
719 u16 len, tag;
719 bool found = false; 720 bool found = false;
720 721
721 if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */ 722 if (lowpan_fetch_skb_u8(skb, &slen) || /* frame length */
722 lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ 723 lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */
723 goto drop; 724 goto drop;
724 725
726 /* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */
727 len = ((iphc0 & 7) << 8) | slen;
728
725 /* 729 /*
726 * check if frame assembling with the same tag is 730 * check if frame assembling with the same tag is
727 * already in progress 731 * already in progress
@@ -736,7 +740,7 @@ lowpan_process_data(struct sk_buff *skb)
736 740
737 /* alloc new frame structure */ 741 /* alloc new frame structure */
738 if (!found) { 742 if (!found) {
739 frame = lowpan_alloc_new_frame(skb, iphc0, len, tag); 743 frame = lowpan_alloc_new_frame(skb, len, tag);
740 if (!frame) 744 if (!frame)
741 goto unlock_and_drop; 745 goto unlock_and_drop;
742 } 746 }
@@ -1004,8 +1008,8 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
1004 tag = fragment_tag++; 1008 tag = fragment_tag++;
1005 1009
1006 /* first fragment header */ 1010 /* first fragment header */
1007 head[0] = LOWPAN_DISPATCH_FRAG1 | (payload_length & 0x7); 1011 head[0] = LOWPAN_DISPATCH_FRAG1 | ((payload_length >> 8) & 0x7);
1008 head[1] = (payload_length >> 3) & 0xff; 1012 head[1] = payload_length & 0xff;
1009 head[2] = tag >> 8; 1013 head[2] = tag >> 8;
1010 head[3] = tag & 0xff; 1014 head[3] = tag & 0xff;
1011 1015