Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  ebt_snat
0004  *
0005  *  Authors:
0006  *  Bart De Schuymer <bdschuym@pandora.be>
0007  *
0008  *  June, 2002
0009  *
0010  */
0011 #include <linux/module.h>
0012 #include <net/sock.h>
0013 #include <linux/if_arp.h>
0014 #include <net/arp.h>
0015 #include <linux/netfilter.h>
0016 #include <linux/netfilter/x_tables.h>
0017 #include <linux/netfilter_bridge/ebtables.h>
0018 #include <linux/netfilter_bridge/ebt_nat.h>
0019 
0020 static unsigned int
0021 ebt_snat_tg(struct sk_buff *skb, const struct xt_action_param *par)
0022 {
0023     const struct ebt_nat_info *info = par->targinfo;
0024 
0025     if (skb_ensure_writable(skb, 0))
0026         return EBT_DROP;
0027 
0028     ether_addr_copy(eth_hdr(skb)->h_source, info->mac);
0029     if (!(info->target & NAT_ARP_BIT) &&
0030         eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
0031         const struct arphdr *ap;
0032         struct arphdr _ah;
0033 
0034         ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
0035         if (ap == NULL)
0036             return EBT_DROP;
0037         if (ap->ar_hln != ETH_ALEN)
0038             goto out;
0039         if (skb_store_bits(skb, sizeof(_ah), info->mac, ETH_ALEN))
0040             return EBT_DROP;
0041     }
0042 out:
0043     return info->target | ~EBT_VERDICT_BITS;
0044 }
0045 
0046 static int ebt_snat_tg_check(const struct xt_tgchk_param *par)
0047 {
0048     const struct ebt_nat_info *info = par->targinfo;
0049     int tmp;
0050 
0051     tmp = info->target | ~EBT_VERDICT_BITS;
0052     if (BASE_CHAIN && tmp == EBT_RETURN)
0053         return -EINVAL;
0054 
0055     if (ebt_invalid_target(tmp))
0056         return -EINVAL;
0057     tmp = info->target | EBT_VERDICT_BITS;
0058     if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
0059         return -EINVAL;
0060     return 0;
0061 }
0062 
0063 static struct xt_target ebt_snat_tg_reg __read_mostly = {
0064     .name       = "snat",
0065     .revision   = 0,
0066     .family     = NFPROTO_BRIDGE,
0067     .table      = "nat",
0068     .hooks      = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING),
0069     .target     = ebt_snat_tg,
0070     .checkentry = ebt_snat_tg_check,
0071     .targetsize = sizeof(struct ebt_nat_info),
0072     .me     = THIS_MODULE,
0073 };
0074 
0075 static int __init ebt_snat_init(void)
0076 {
0077     return xt_register_target(&ebt_snat_tg_reg);
0078 }
0079 
0080 static void __exit ebt_snat_fini(void)
0081 {
0082     xt_unregister_target(&ebt_snat_tg_reg);
0083 }
0084 
0085 module_init(ebt_snat_init);
0086 module_exit(ebt_snat_fini);
0087 MODULE_DESCRIPTION("Ebtables: Source MAC address translation");
0088 MODULE_LICENSE("GPL");