From 0175052cf1b0c6294441e87a736a1c712a03aad5 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Fri, 4 Mar 2016 17:05:56 +0100 Subject: [PATCH] set transport header when injecting 802.3 frames Resetting the headers is not enoug, we have to make sure the transport header points the right position and the skb->protocol is initialized to the payload protocol. --- src/wtp/kmod/capwap_private.c | 47 ++++++++++++++++++++++------------- src/wtp/kmod/config.h | 2 +- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/wtp/kmod/capwap_private.c b/src/wtp/kmod/capwap_private.c index 5358358..bfedbe5 100644 --- a/src/wtp/kmod/capwap_private.c +++ b/src/wtp/kmod/capwap_private.c @@ -136,18 +136,29 @@ struct sc_capwap_session* sc_capwap_recvunknownkeepalive(struct sc_capwap_sessio static void sc_send_8023(struct sk_buff *skb, struct net_device *dev) { - skb_reset_network_header(skb); - skb_reset_mac_header(skb); + struct ethhdr *eh; + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) + return; + + /* drop conntrack reference */ + nf_reset(skb); + + /* detach skb from CAPWAP */ + skb_orphan(skb); secpath_reset(skb); - /* drop any routing info */ - skb_dst_drop(skb); - - /* drop conntrack reference */ - nf_reset(skb); + /* drop any routing info */ + skb_dst_drop(skb); skb->dev = dev; + skb_reset_mac_header(skb); + eh = eth_hdr(skb); + if (likely(eth_proto_is_802_3(eh->h_proto))) + skb->protocol = eh->h_proto; + else + skb->protocol = htons(ETH_P_802_2); + skb_set_network_header(skb, ETH_HLEN); /* Force the device to verify it. */ skb->ip_summed = CHECKSUM_NONE; @@ -164,16 +175,8 @@ static void sc_send_80211(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "capwap inject: %s: hdr: %p\n", dev->name, skb->data); - hdr = (struct ieee80211_hdr *)skb->data; - hdrlen = ieee80211_hdrlen(hdr->frame_control); - - skb_set_mac_header(skb, hdrlen); - skb_set_network_header(skb, hdrlen); - skb_set_transport_header(skb, hdrlen); - - skb->protocol = htons(ETH_P_CONTROL); - info->flags |= IEEE80211_TX_CTL_INJECTED; - + /* detach skb from CAPWAP */ + skb_orphan(skb); secpath_reset(skb); /* drop any routing info */ @@ -182,8 +185,18 @@ static void sc_send_80211(struct sk_buff *skb, struct net_device *dev) /* drop conntrack reference */ nf_reset(skb); + hdr = (struct ieee80211_hdr *)skb->data; + hdrlen = ieee80211_hdrlen(hdr->frame_control); + skb->dev = dev; + skb_set_mac_header(skb, hdrlen); + skb_set_network_header(skb, hdrlen); + skb_set_transport_header(skb, hdrlen); + + skb->protocol = htons(ETH_P_CONTROL); + info->flags |= IEEE80211_TX_CTL_INJECTED; + /* Force the device to verify it. */ skb->ip_summed = CHECKSUM_NONE; diff --git a/src/wtp/kmod/config.h b/src/wtp/kmod/config.h index d4c3990..453c2a3 100644 --- a/src/wtp/kmod/config.h +++ b/src/wtp/kmod/config.h @@ -1,7 +1,7 @@ #ifndef __KMOD_CONFIG_HEADER__ #define __KMOD_CONFIG_HEADER__ -#define DEBUGKMOD 1 +// #define DEBUGKMOD 1 #ifdef DEBUGKMOD #define TRACEKMOD(s, args...) printk(s, ##args)