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 172d06d4a5cc107046508d860a0b47dbc43b829b79Jan Engelhardtstatic unsigned int 184b560b447df83368df44bd3712c0c39b1d79ba04Jan Engelhardtebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 207eb3558655aaa87a3e71a0c065dfaddda521fa6dJan Engelhardt const struct ebt_nat_info *info = par->targinfo; 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22eb1197bc0e20d3ceb450883dbd181460252f0306Joonwoo Park if (!skb_make_writable(skb, 0)) 231b04ab4597725f75f94942da9aa40daa7b9a4bd9Joonwoo Park return EBT_DROP; 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2504091142826e5823e31cc6418942ac447b3edb0aJoe Perches ether_addr_copy(eth_hdr(skb)->h_dest, info->mac); 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return info->target; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29135367b8f6a18507af6b9a6910a14b5699415309Jan Engelhardtstatic int ebt_dnat_tg_check(const struct xt_tgchk_param *par) 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt const struct ebt_nat_info *info = par->targinfo; 32af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt unsigned int hook_mask; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (BASE_CHAIN && info->target == EBT_RETURN) 35d6b00a5345ce4e86e8b00a88bb84a2c0c1f69ddcJan Engelhardt return -EINVAL; 36af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt 37af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); 38af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt if ((strcmp(par->table, "nat") != 0 || 39af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt (hook_mask & ~((1 << NF_BR_PRE_ROUTING) | 40af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt (1 << NF_BR_LOCAL_OUT)))) && 41af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt (strcmp(par->table, "broute") != 0 || 42af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37fJan Engelhardt hook_mask & ~(1 << NF_BR_BROUTING))) 43d6b00a5345ce4e86e8b00a88bb84a2c0c1f69ddcJan Engelhardt return -EINVAL; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (INVALID_TARGET) 45d6b00a5345ce4e86e8b00a88bb84a2c0c1f69ddcJan Engelhardt return -EINVAL; 46d6b00a5345ce4e86e8b00a88bb84a2c0c1f69ddcJan Engelhardt return 0; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49043ef46c7690bfdbd5b012e15812a14a19ca5604Jan Engelhardtstatic struct xt_target ebt_dnat_tg_reg __read_mostly = { 50043ef46c7690bfdbd5b012e15812a14a19ca5604Jan Engelhardt .name = "dnat", 51001a18d369f4813ed792629ff4a9a6ade2a4a031Jan Engelhardt .revision = 0, 52001a18d369f4813ed792629ff4a9a6ade2a4a031Jan Engelhardt .family = NFPROTO_BRIDGE, 53f2ff525c8dae57b3cda51d76443f60f764f34202Jan Engelhardt .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) | 54f2ff525c8dae57b3cda51d76443f60f764f34202Jan Engelhardt (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING), 552d06d4a5cc107046508d860a0b47dbc43b829b79Jan Engelhardt .target = ebt_dnat_tg, 562d06d4a5cc107046508d860a0b47dbc43b829b79Jan Engelhardt .checkentry = ebt_dnat_tg_check, 57fc0e3df4f00a5f62c2f2fce84bf496136b58c474Florian Westphal .targetsize = sizeof(struct ebt_nat_info), 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .me = THIS_MODULE, 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6165b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic int __init ebt_dnat_init(void) 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 63043ef46c7690bfdbd5b012e15812a14a19ca5604Jan Engelhardt return xt_register_target(&ebt_dnat_tg_reg); 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6665b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic void __exit ebt_dnat_fini(void) 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 68043ef46c7690bfdbd5b012e15812a14a19ca5604Jan Engelhardt xt_unregister_target(&ebt_dnat_tg_reg); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7165b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_init(ebt_dnat_init); 7265b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_exit(ebt_dnat_fini); 73f776c4cda449bab463f5388eb07bd63dc52e2b13Jan EngelhardtMODULE_DESCRIPTION("Ebtables: Destination MAC address translation"); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 75