Skip to content

Commit

Permalink
Staging: batman-adv: add gateway IPv6 support by filtering DHCPv6 mes…
Browse files Browse the repository at this point in the history
…sages

Some additional checks will be needed in case of extension headers
like the fragmentation or hop-by-hop (for jumbo frames for example)
headers or ipsec stuff. But this patch should do for most people
for now, the rest can be added with a later one.

Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Acked-by: Linus Lüssing <linus.luessing@web.de>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Marek Lindner authored and Greg Kroah-Hartman committed Nov 29, 2010
1 parent c9c556b commit 003db3b
Showing 1 changed file with 31 additions and 9 deletions.
40 changes: 31 additions & 9 deletions drivers/staging/batman-adv/gateway_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "gateway_common.h"
#include "hard-interface.h"
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/if_vlan.h>

Expand Down Expand Up @@ -403,6 +404,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
{
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr;
unsigned int header_len = 0;

Expand All @@ -424,25 +426,45 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
}

/* check for ip header */
if (ntohs(ethhdr->h_proto) != ETH_P_IP)
return 0;
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_IP:
if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
return 0;
iphdr = (struct iphdr *)(skb->data + header_len);
header_len += iphdr->ihl * 4;

if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
return 0;
iphdr = (struct iphdr *)(skb->data + header_len);
header_len += iphdr->ihl * 4;
/* check for udp header */
if (iphdr->protocol != IPPROTO_UDP)
return 0;

break;
case ETH_P_IPV6:
if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
return 0;
ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
header_len += sizeof(struct ipv6hdr);

/* check for udp header */
if (iphdr->protocol != IPPROTO_UDP)
/* check for udp header */
if (ipv6hdr->nexthdr != IPPROTO_UDP)
return 0;

break;
default:
return 0;
}

if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
return 0;
udphdr = (struct udphdr *)(skb->data + header_len);
header_len += sizeof(struct udphdr);

/* check for bootp port */
if (ntohs(udphdr->dest) != 67)
if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
(ntohs(udphdr->dest) != 67))
return 0;

if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
(ntohs(udphdr->dest) != 547))
return 0;

if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
Expand Down

0 comments on commit 003db3b

Please sign in to comment.