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_ipv4/ipt_mac.h> 7#include <linux/netfilter_ipv4/ip_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 ipt_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 30ipt_mac_checkentry(const char *tablename, 31 const struct ipt_ip *ip, 32 void *matchinfo, 33 unsigned int matchsize, 34 unsigned int hook_mask) 35{ 36 /* FORWARD isn't always valid, but it's nice to be able to do --RR */ 37 if (hook_mask 38 & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 39 | (1 << NF_IP_FORWARD))) { 40 printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 41 return 0; 42 } 43 44 if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info))) 45 return 0; 46 47 return 1; 48} 49 50static struct ipt_match mac_match 51= { { NULL, NULL }, "mac", &match, &ipt_mac_checkentry, NULL, THIS_MODULE }; 52 53static int __init init(void) 54{ 55 return ipt_register_match(&mac_match); 56} 57 58static void __exit fini(void) 59{ 60 ipt_unregister_match(&mac_match); 61} 62 63module_init(init); 64module_exit(fini); 65MODULE_LICENSE("GPL"); 66