ebt_dnat.c revision 18219d3f7d6a5bc43825a41e0763158efbdb80d3
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ebt_dnat 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Authors: 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bart De Schuymer <bdschuym@pandora.be> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * June, 2002 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1018219d3f7d6a5bc43825a41e0763158efbdb80d3Jan Engelhardt#include <linux/module.h> 1118219d3f7d6a5bc43825a41e0763158efbdb80d3Jan Engelhardt#include <net/sock.h> 122ca7b0ac022aa0158599178fe1056b1ba9ec8b97Herbert Xu#include <linux/netfilter.h> 1318219d3f7d6a5bc43825a41e0763158efbdb80d3Jan Engelhardt#include <linux/netfilter/x_tables.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netfilter_bridge/ebtables.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netfilter_bridge/ebt_nat.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 173db05fea51cdb162cfa8f69e9cfb9e228919d2a9Herbert Xustatic int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct net_device *in, const struct net_device *out, 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const void *data, unsigned int datalen) 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21abfdf1c48907f78ad7d943b77ea180bf5504564fJan Engelhardt const struct ebt_nat_info *info = data; 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23eb1197bc0e20d3ceb450883dbd181460252f0306Joonwoo Park if (!skb_make_writable(skb, 0)) 241b04ab4597725f75f94942da9aa40daa7b9a4bd9Joonwoo Park return EBT_DROP; 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 263db05fea51cdb162cfa8f69e9cfb9e228919d2a9Herbert Xu memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN); 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return info->target; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct ebt_entry *e, void *data, unsigned int datalen) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 33abfdf1c48907f78ad7d943b77ea180bf5504564fJan Engelhardt const struct ebt_nat_info *info = data; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (BASE_CHAIN && info->target == EBT_RETURN) 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds CLEAR_BASE_CHAIN_BIT; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (strcmp(tablename, "nat") || 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (INVALID_TARGET) 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4730083c9500b8aa3bc48579eaadb5068ad057afbdJan Engelhardtstatic struct ebt_target dnat __read_mostly = { 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = EBT_DNAT_TARGET, 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .target = ebt_target_dnat, 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .check = ebt_target_dnat_check, 5118219d3f7d6a5bc43825a41e0763158efbdb80d3Jan Engelhardt .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)), 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .me = THIS_MODULE, 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5565b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic int __init ebt_dnat_init(void) 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ebt_register_target(&dnat); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6065b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic void __exit ebt_dnat_fini(void) 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ebt_unregister_target(&dnat); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6565b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_init(ebt_dnat_init); 6665b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_exit(ebt_dnat_fini); 67f776c4cda449bab463f5388eb07bd63dc52e2b13Jan EngelhardtMODULE_DESCRIPTION("Ebtables: Destination MAC address translation"); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 69