|
@@ -655,24 +655,29 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
|
|
|
struct iphdr *iphdr;
|
|
|
struct ipv6hdr *ipv6hdr;
|
|
|
struct udphdr *udphdr;
|
|
|
+ struct vlan_ethhdr *vhdr;
|
|
|
+ __be16 proto;
|
|
|
|
|
|
/* check for ethernet header */
|
|
|
if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
|
|
|
return false;
|
|
|
ethhdr = (struct ethhdr *)skb->data;
|
|
|
+ proto = ethhdr->h_proto;
|
|
|
*header_len += ETH_HLEN;
|
|
|
|
|
|
/* check for initial vlan header */
|
|
|
- if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
|
|
|
+ if (proto == htons(ETH_P_8021Q)) {
|
|
|
if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
|
|
|
return false;
|
|
|
- ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
|
|
|
+
|
|
|
+ vhdr = (struct vlan_ethhdr *)skb->data;
|
|
|
+ proto = vhdr->h_vlan_encapsulated_proto;
|
|
|
*header_len += VLAN_HLEN;
|
|
|
}
|
|
|
|
|
|
/* check for ip header */
|
|
|
- switch (ntohs(ethhdr->h_proto)) {
|
|
|
- case ETH_P_IP:
|
|
|
+ switch (proto) {
|
|
|
+ case htons(ETH_P_IP):
|
|
|
if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
|
|
|
return false;
|
|
|
iphdr = (struct iphdr *)(skb->data + *header_len);
|
|
@@ -683,7 +688,7 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
|
|
|
return false;
|
|
|
|
|
|
break;
|
|
|
- case ETH_P_IPV6:
|
|
|
+ case htons(ETH_P_IPV6):
|
|
|
if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
|
|
|
return false;
|
|
|
ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
|
|
@@ -710,11 +715,11 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
|
|
|
*header_len += sizeof(*udphdr);
|
|
|
|
|
|
/* check for bootp port */
|
|
|
- if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
|
|
|
+ if ((proto == htons(ETH_P_IP)) &&
|
|
|
(ntohs(udphdr->dest) != 67))
|
|
|
return false;
|
|
|
|
|
|
- if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
|
|
|
+ if ((proto == htons(ETH_P_IPV6)) &&
|
|
|
(ntohs(udphdr->dest) != 547))
|
|
|
return false;
|
|
|
|