static unsigned int hwaddr_in_hook_fn(struct nf_hook_ops const *ops, #endif struct sk_buff *skb, struct net_device const *in, struct net_device const *out, int (*okfn)(struct sk_buff *)) { struct net_device *target = NULL; struct ethhdr *lhdr = NULL; struct iphdr *nhdr = NULL; if (!in) return NF_ACCEPT; if (in->type != ARPHRD_ETHER && in->type != ARPHRD_IEEE802) return NF_ACCEPT; if (skb->mac_len != ETH_HLEN) return NF_ACCEPT; lhdr = eth_hdr(skb); nhdr = ip_hdr(skb); target = __ip_dev_find(dev_net(in), nhdr->daddr, false); if (target == in) hwaddr_update(in, nhdr->saddr, nhdr->daddr, lhdr->h_source, ETH_ALEN); return NF_ACCEPT; }
static unsigned int hwaddr_input_hook( #if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) unsigned unused, #else struct nf_hook_ops const *unused, #endif struct sk_buff *skb, struct net_device const *in, struct net_device const *out, int (*okfn)(struct sk_buff *)) { struct net_device *target = NULL; struct ethhdr *llhdr = NULL; struct iphdr *nhdr = NULL; if (!in) return NF_ACCEPT; if (in->type != ARPHRD_ETHER && in->type != ARPHRD_IEEE802) return NF_ACCEPT; llhdr = eth_hdr(skb); nhdr = ip_hdr(skb); target = __ip_dev_find(dev_net(in), nhdr->daddr, false); if (target == in) hwaddr_update(target, nhdr->saddr, nhdr->daddr, llhdr->h_source, ETH_ALEN); return NF_ACCEPT; }