summaryrefslogtreecommitdiff
path: root/net/ieee802154/6lowpan/rx.c
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2015-09-02 15:21:26 +0300
committerMarcel Holtmann <marcel@holtmann.org>2015-09-17 14:20:03 +0300
commitfaf7d36e5ecd16ab090c82d14bff31f7ab2f70e6 (patch)
tree8599aabdec9d74a3815b247cf2a2d0eb58c45826 /net/ieee802154/6lowpan/rx.c
parent72a5e6bb5120d6464c9e7855c5a22555ede819dc (diff)
downloadlinux-faf7d36e5ecd16ab090c82d14bff31f7ab2f70e6.tar.xz
ieee802154: 6lowpan: add generic lowpan header check
This patch introduce an earlier check if a 6LoWPAN frame can be valid. This contains at first for checking if the header contains a dispatch byte and isn't the nalp dispatch value, which means it isn't a 6LoWPAN packet. Also we add a check if we can derference the dispatch value by checking if skb->len is unequal zero. Reviewed-by: Stefan Schmidt <stefan@osg.samsung.com> Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/ieee802154/6lowpan/rx.c')
-rw-r--r--net/ieee802154/6lowpan/rx.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/net/ieee802154/6lowpan/rx.c b/net/ieee802154/6lowpan/rx.c
index fded1099fae0..c46cab3b0ff4 100644
--- a/net/ieee802154/6lowpan/rx.c
+++ b/net/ieee802154/6lowpan/rx.c
@@ -15,8 +15,11 @@
#include "6lowpan_i.h"
+#define LOWPAN_DISPATCH_FIRST 0xc0
#define LOWPAN_DISPATCH_FRAG_MASK 0xf8
+#define LOWPAN_DISPATCH_NALP 0x00
+
static int lowpan_give_skb_to_device(struct sk_buff *skb)
{
skb->protocol = htons(ETH_P_IPV6);
@@ -162,13 +165,36 @@ rxh_next:
#undef CALL_RXH
}
+static inline bool lowpan_is_nalp(u8 dispatch)
+{
+ return (dispatch & LOWPAN_DISPATCH_FIRST) == LOWPAN_DISPATCH_NALP;
+}
+
+/* lowpan_rx_h_check checks on generic 6LoWPAN requirements
+ * in MAC and 6LoWPAN header.
+ *
+ * Don't manipulate the skb here, it could be shared buffer.
+ */
+static inline bool lowpan_rx_h_check(struct sk_buff *skb)
+{
+ /* check if we can dereference the dispatch */
+ if (unlikely(!skb->len))
+ return false;
+
+ if (lowpan_is_nalp(*skb_network_header(skb)))
+ return false;
+
+ return true;
+}
+
static int lowpan_rcv(struct sk_buff *skb, struct net_device *wdev,
struct packet_type *pt, struct net_device *orig_wdev)
{
struct net_device *ldev;
if (wdev->type != ARPHRD_IEEE802154 ||
- skb->pkt_type == PACKET_OTHERHOST)
+ skb->pkt_type == PACKET_OTHERHOST ||
+ !lowpan_rx_h_check(skb))
return NET_RX_DROP;
ldev = wdev->ieee802154_ptr->lowpan_dev;