#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>
{
struct ethhdr *ethhdr;
struct iphdr *iphdr;
+ struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr;
unsigned int header_len = 0;
}
/* 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;
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)