1/* module that allows mangling of the arp payload */ 2#include <linux/module.h> 3#include <linux/netfilter.h> 4#include <linux/netfilter_arp/arpt_mangle.h> 5#include <net/sock.h> 6 7MODULE_LICENSE("GPL"); 8MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 9MODULE_DESCRIPTION("arptables arp payload mangle target"); 10 11static unsigned int 12target(struct sk_buff *skb, const struct xt_action_param *par) 13{ 14 const struct arpt_mangle *mangle = par->targinfo; 15 const struct arphdr *arp; 16 unsigned char *arpptr; 17 int pln, hln; 18 19 if (!skb_make_writable(skb, skb->len)) 20 return NF_DROP; 21 22 arp = arp_hdr(skb); 23 arpptr = skb_network_header(skb) + sizeof(*arp); 24 pln = arp->ar_pln; 25 hln = arp->ar_hln; 26 /* We assume that pln and hln were checked in the match */ 27 if (mangle->flags & ARPT_MANGLE_SDEV) { 28 if (ARPT_DEV_ADDR_LEN_MAX < hln || 29 (arpptr + hln > skb_tail_pointer(skb))) 30 return NF_DROP; 31 memcpy(arpptr, mangle->src_devaddr, hln); 32 } 33 arpptr += hln; 34 if (mangle->flags & ARPT_MANGLE_SIP) { 35 if (ARPT_MANGLE_ADDR_LEN_MAX < pln || 36 (arpptr + pln > skb_tail_pointer(skb))) 37 return NF_DROP; 38 memcpy(arpptr, &mangle->u_s.src_ip, pln); 39 } 40 arpptr += pln; 41 if (mangle->flags & ARPT_MANGLE_TDEV) { 42 if (ARPT_DEV_ADDR_LEN_MAX < hln || 43 (arpptr + hln > skb_tail_pointer(skb))) 44 return NF_DROP; 45 memcpy(arpptr, mangle->tgt_devaddr, hln); 46 } 47 arpptr += hln; 48 if (mangle->flags & ARPT_MANGLE_TIP) { 49 if (ARPT_MANGLE_ADDR_LEN_MAX < pln || 50 (arpptr + pln > skb_tail_pointer(skb))) 51 return NF_DROP; 52 memcpy(arpptr, &mangle->u_t.tgt_ip, pln); 53 } 54 return mangle->target; 55} 56 57static int checkentry(const struct xt_tgchk_param *par) 58{ 59 const struct arpt_mangle *mangle = par->targinfo; 60 61 if (mangle->flags & ~ARPT_MANGLE_MASK || 62 !(mangle->flags & ARPT_MANGLE_MASK)) 63 return -EINVAL; 64 65 if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && 66 mangle->target != XT_CONTINUE) 67 return -EINVAL; 68 return 0; 69} 70 71static struct xt_target arpt_mangle_reg __read_mostly = { 72 .name = "mangle", 73 .family = NFPROTO_ARP, 74 .target = target, 75 .targetsize = sizeof(struct arpt_mangle), 76 .checkentry = checkentry, 77 .me = THIS_MODULE, 78}; 79 80static int __init arpt_mangle_init(void) 81{ 82 return xt_register_target(&arpt_mangle_reg); 83} 84 85static void __exit arpt_mangle_fini(void) 86{ 87 xt_unregister_target(&arpt_mangle_reg); 88} 89 90module_init(arpt_mangle_init); 91module_exit(arpt_mangle_fini); 92