1/* Kernel module to match MAC address parameters. */ 2#include <linux/module.h> 3#include <linux/skbuff.h> 4#include <linux/if_ether.h> 5 6#include <linux/netfilter_ipv6/ip6t_mac.h> 7#include <linux/netfilter_ipv6/ip6_tables.h> 8 9static int 10match(const struct sk_buff *skb, 11 const struct net_device *in, 12 const struct net_device *out, 13 const void *matchinfo, 14 int offset, 15 const void *hdr, 16 u_int16_t datalen, 17 int *hotdrop) 18{ 19 const struct ip6t_mac_info *info = matchinfo; 20 21 /* Is mac pointer valid? */ 22 return (skb->mac.raw >= skb->head 23 && (skb->mac.raw + ETH_HLEN) <= skb->data 24 /* If so, compare... */ 25 && ((memcmp(skb->mac.ethernet->h_source, info->srcaddr, ETH_ALEN) 26 == 0) ^ info->invert)); 27} 28 29static int 30ip6t_mac_checkentry(const char *tablename, 31 const struct ip6t_ip6 *ip, 32 void *matchinfo, 33 unsigned int matchsize, 34 unsigned int hook_mask) 35{ 36 if (hook_mask 37 & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) 38 | (1 << NF_IP6_FORWARD))) { 39 printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or" 40 " FORWARD\n"); 41 return 0; 42 } 43 44 if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info))) 45 return 0; 46 47 return 1; 48} 49 50static struct ip6t_match mac_match 51= { { NULL, NULL }, "mac", &match, &ip6t_mac_checkentry, NULL, THIS_MODULE }; 52 53static int __init init(void) 54{ 55 return ip6t_register_match(&mac_match); 56} 57 58static void __exit fini(void) 59{ 60 ip6t_unregister_match(&mac_match); 61} 62 63module_init(init); 64module_exit(fini); 65MODULE_LICENSE("GPL"); 66MODULE_DESCRIPTION("MAC address matching module for IPv6"); 67