linux/net/ipv4/netfilter/arpt_mangle.c
<<
>>
Prefs
   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