ebt_snat.c (2077B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ebt_snat 4 * 5 * Authors: 6 * Bart De Schuymer <bdschuym@pandora.be> 7 * 8 * June, 2002 9 * 10 */ 11#include <linux/module.h> 12#include <net/sock.h> 13#include <linux/if_arp.h> 14#include <net/arp.h> 15#include <linux/netfilter.h> 16#include <linux/netfilter/x_tables.h> 17#include <linux/netfilter_bridge/ebtables.h> 18#include <linux/netfilter_bridge/ebt_nat.h> 19 20static unsigned int 21ebt_snat_tg(struct sk_buff *skb, const struct xt_action_param *par) 22{ 23 const struct ebt_nat_info *info = par->targinfo; 24 25 if (skb_ensure_writable(skb, 0)) 26 return EBT_DROP; 27 28 ether_addr_copy(eth_hdr(skb)->h_source, info->mac); 29 if (!(info->target & NAT_ARP_BIT) && 30 eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) { 31 const struct arphdr *ap; 32 struct arphdr _ah; 33 34 ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah); 35 if (ap == NULL) 36 return EBT_DROP; 37 if (ap->ar_hln != ETH_ALEN) 38 goto out; 39 if (skb_store_bits(skb, sizeof(_ah), info->mac, ETH_ALEN)) 40 return EBT_DROP; 41 } 42out: 43 return info->target | ~EBT_VERDICT_BITS; 44} 45 46static int ebt_snat_tg_check(const struct xt_tgchk_param *par) 47{ 48 const struct ebt_nat_info *info = par->targinfo; 49 int tmp; 50 51 tmp = info->target | ~EBT_VERDICT_BITS; 52 if (BASE_CHAIN && tmp == EBT_RETURN) 53 return -EINVAL; 54 55 if (ebt_invalid_target(tmp)) 56 return -EINVAL; 57 tmp = info->target | EBT_VERDICT_BITS; 58 if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) 59 return -EINVAL; 60 return 0; 61} 62 63static struct xt_target ebt_snat_tg_reg __read_mostly = { 64 .name = "snat", 65 .revision = 0, 66 .family = NFPROTO_BRIDGE, 67 .table = "nat", 68 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING), 69 .target = ebt_snat_tg, 70 .checkentry = ebt_snat_tg_check, 71 .targetsize = sizeof(struct ebt_nat_info), 72 .me = THIS_MODULE, 73}; 74 75static int __init ebt_snat_init(void) 76{ 77 return xt_register_target(&ebt_snat_tg_reg); 78} 79 80static void __exit ebt_snat_fini(void) 81{ 82 xt_unregister_target(&ebt_snat_tg_reg); 83} 84 85module_init(ebt_snat_init); 86module_exit(ebt_snat_fini); 87MODULE_DESCRIPTION("Ebtables: Source MAC address translation"); 88MODULE_LICENSE("GPL");