5 * Bart De Schuymer <bdschuym@pandora.be>
10 #include <linux/module.h>
12 #include <linux/if_arp.h>
14 #include <linux/netfilter.h>
15 #include <linux/netfilter/x_tables.h>
16 #include <linux/netfilter_bridge/ebtables.h>
17 #include <linux/netfilter_bridge/ebt_nat.h>
20 ebt_snat_tg(struct sk_buff
*skb
, const struct xt_action_param
*par
)
22 const struct ebt_nat_info
*info
= par
->targinfo
;
24 if (!skb_make_writable(skb
, 0))
27 memcpy(eth_hdr(skb
)->h_source
, info
->mac
, ETH_ALEN
);
28 if (!(info
->target
& NAT_ARP_BIT
) &&
29 eth_hdr(skb
)->h_proto
== htons(ETH_P_ARP
)) {
30 const struct arphdr
*ap
;
33 ap
= skb_header_pointer(skb
, 0, sizeof(_ah
), &_ah
);
36 if (ap
->ar_hln
!= ETH_ALEN
)
38 if (skb_store_bits(skb
, sizeof(_ah
), info
->mac
,ETH_ALEN
))
42 return info
->target
| ~EBT_VERDICT_BITS
;
45 static int ebt_snat_tg_check(const struct xt_tgchk_param
*par
)
47 const struct ebt_nat_info
*info
= par
->targinfo
;
50 tmp
= info
->target
| ~EBT_VERDICT_BITS
;
51 if (BASE_CHAIN
&& tmp
== EBT_RETURN
)
54 if (tmp
< -NUM_STANDARD_TARGETS
|| tmp
>= 0)
56 tmp
= info
->target
| EBT_VERDICT_BITS
;
57 if ((tmp
& ~NAT_ARP_BIT
) != ~NAT_ARP_BIT
)
62 static struct xt_target ebt_snat_tg_reg __read_mostly
= {
65 .family
= NFPROTO_BRIDGE
,
67 .hooks
= (1 << NF_BR_NUMHOOKS
) | (1 << NF_BR_POST_ROUTING
),
68 .target
= ebt_snat_tg
,
69 .checkentry
= ebt_snat_tg_check
,
70 .targetsize
= sizeof(struct ebt_nat_info
),
74 static int __init
ebt_snat_init(void)
76 return xt_register_target(&ebt_snat_tg_reg
);
79 static void __exit
ebt_snat_fini(void)
81 xt_unregister_target(&ebt_snat_tg_reg
);
84 module_init(ebt_snat_init
);
85 module_exit(ebt_snat_fini
);
86 MODULE_DESCRIPTION("Ebtables: Source MAC address translation");
87 MODULE_LICENSE("GPL");