Commit bf8b9a9c authored by Grzegorz Kolodziejczyk's avatar Grzegorz Kolodziejczyk Committed by Marcel Holtmann

Bluetooth: bnep: Add support to extended headers of control frames

Handling extended headers of control frames is required BNEP
functionality. This patch refractor bnep rx frame handling function.
Extended header for control frames shouldn't be omitted as it was
previously done. Every control frame should be checked if it contains
extended header and then every extension should be parsed separately.
Signed-off-by: default avatarGrzegorz Kolodziejczyk <grzegorz.kolodziejczyk@tieto.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 0477e2e8
...@@ -292,29 +292,55 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) ...@@ -292,29 +292,55 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
{ {
struct net_device *dev = s->dev; struct net_device *dev = s->dev;
struct sk_buff *nskb; struct sk_buff *nskb;
u8 type; u8 type, ctrl_type;
dev->stats.rx_bytes += skb->len; dev->stats.rx_bytes += skb->len;
type = *(u8 *) skb->data; type = *(u8 *) skb->data;
skb_pull(skb, 1); skb_pull(skb, 1);
ctrl_type = *(u8 *)skb->data;
if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen))
goto badframe; goto badframe;
if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) { if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
bnep_rx_control(s, skb->data, skb->len); if (bnep_rx_control(s, skb->data, skb->len) < 0) {
kfree_skb(skb); dev->stats.tx_errors++;
return 0; kfree_skb(skb);
} return 0;
}
skb_reset_mac_header(skb); if (!(type & BNEP_EXT_HEADER)) {
kfree_skb(skb);
return 0;
}
/* Verify and pull out header */ /* Verify and pull ctrl message since it's already processed */
if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) switch (ctrl_type) {
goto badframe; case BNEP_SETUP_CONN_REQ:
/* Pull: ctrl type (1 b), len (1 b), data (len bytes) */
if (!skb_pull(skb, 2 + *(u8 *)(skb->data + 1) * 2))
goto badframe;
break;
case BNEP_FILTER_MULTI_ADDR_SET:
case BNEP_FILTER_NET_TYPE_SET:
/* Pull: ctrl type (1 b), len (2 b), data (len bytes) */
if (!skb_pull(skb, 3 + *(u16 *)(skb->data + 1) * 2))
goto badframe;
break;
default:
kfree_skb(skb);
return 0;
}
} else {
skb_reset_mac_header(skb);
s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); /* Verify and pull out header */
if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
goto badframe;
s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
}
if (type & BNEP_EXT_HEADER) { if (type & BNEP_EXT_HEADER) {
if (bnep_rx_extension(s, skb) < 0) if (bnep_rx_extension(s, skb) < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment