Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / ebtables / extensions / ebt_nat.c
blobe6afbf8f3a3f84f5d5b7f8757abe2ddab1cb2400
1 /* ebt_nat
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
6 * June, 2002
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <getopt.h>
13 #include "../include/ebtables_u.h"
14 #include <netinet/ether.h>
15 #include <linux/netfilter_bridge/ebt_nat.h>
17 static int to_source_supplied, to_dest_supplied;
19 #define NAT_S '1'
20 #define NAT_D '1'
21 #define NAT_S_TARGET '2'
22 #define NAT_D_TARGET '2'
23 #define NAT_S_ARP '3'
24 static struct option opts_s[] =
26 { "to-source" , required_argument, 0, NAT_S },
27 { "to-src" , required_argument, 0, NAT_S },
28 { "snat-target" , required_argument, 0, NAT_S_TARGET },
29 { "snat-arp" , no_argument, 0, NAT_S_ARP },
30 { 0 }
33 static struct option opts_d[] =
35 { "to-destination", required_argument, 0, NAT_D },
36 { "to-dst" , required_argument, 0, NAT_D },
37 { "dnat-target" , required_argument, 0, NAT_D_TARGET },
38 { 0 }
41 static void print_help_s()
43 printf(
44 "snat options:\n"
45 " --to-src address : MAC address to map source to\n"
46 " --snat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"
47 " --snat-arp : also change src address in arp msg\n");
50 static void print_help_d()
52 printf(
53 "dnat options:\n"
54 " --to-dst address : MAC address to map destination to\n"
55 " --dnat-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
58 static void init_s(struct ebt_entry_target *target)
60 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
62 to_source_supplied = 0;
63 natinfo->target = EBT_ACCEPT;
64 return;
67 static void init_d(struct ebt_entry_target *target)
69 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
71 to_dest_supplied = 0;
72 natinfo->target = EBT_ACCEPT;
73 return;
76 #define OPT_SNAT 0x01
77 #define OPT_SNAT_TARGET 0x02
78 #define OPT_SNAT_ARP 0x04
79 static int parse_s(int c, char **argv, int argc,
80 const struct ebt_u_entry *entry, unsigned int *flags,
81 struct ebt_entry_target **target)
83 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
84 struct ether_addr *addr;
86 switch (c) {
87 case NAT_S:
88 ebt_check_option2(flags, OPT_SNAT);
89 to_source_supplied = 1;
90 if (!(addr = ether_aton(optarg)))
91 ebt_print_error2("Problem with specified --to-source mac");
92 memcpy(natinfo->mac, addr, ETH_ALEN);
93 break;
94 case NAT_S_TARGET:
95 { int tmp;
96 ebt_check_option2(flags, OPT_SNAT_TARGET);
97 if (FILL_TARGET(optarg, tmp))
98 ebt_print_error2("Illegal --snat-target target");
99 natinfo->target = (natinfo->target & ~EBT_VERDICT_BITS) | (tmp & EBT_VERDICT_BITS);
101 break;
102 case NAT_S_ARP:
103 ebt_check_option2(flags, OPT_SNAT_ARP);
104 natinfo->target ^= NAT_ARP_BIT;
105 break;
106 default:
107 return 0;
109 return 1;
112 #define OPT_DNAT 0x01
113 #define OPT_DNAT_TARGET 0x02
114 static int parse_d(int c, char **argv, int argc,
115 const struct ebt_u_entry *entry, unsigned int *flags,
116 struct ebt_entry_target **target)
118 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
119 struct ether_addr *addr;
121 switch (c) {
122 case NAT_D:
123 ebt_check_option2(flags, OPT_DNAT);
124 to_dest_supplied = 1;
125 if (!(addr = ether_aton(optarg)))
126 ebt_print_error2("Problem with specified --to-destination mac");
127 memcpy(natinfo->mac, addr, ETH_ALEN);
128 break;
129 case NAT_D_TARGET:
130 ebt_check_option2(flags, OPT_DNAT_TARGET);
131 if (FILL_TARGET(optarg, natinfo->target))
132 ebt_print_error2("Illegal --dnat-target target");
133 break;
134 default:
135 return 0;
137 return 1;
140 static void final_check_s(const struct ebt_u_entry *entry,
141 const struct ebt_entry_target *target, const char *name,
142 unsigned int hookmask, unsigned int time)
144 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
146 if (BASE_CHAIN && (natinfo->target | ~EBT_VERDICT_BITS) == EBT_RETURN) {
147 ebt_print_error("--snat-target RETURN not allowed on base chain");
148 return;
150 CLEAR_BASE_CHAIN_BIT;
151 if ((hookmask & ~(1 << NF_BR_POST_ROUTING)) || strcmp(name, "nat")) {
152 ebt_print_error("Wrong chain for snat");
153 } else if (time == 0 && to_source_supplied == 0)
154 ebt_print_error("No snat address supplied");
157 static void final_check_d(const struct ebt_u_entry *entry,
158 const struct ebt_entry_target *target, const char *name,
159 unsigned int hookmask, unsigned int time)
161 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
163 if (BASE_CHAIN && natinfo->target == EBT_RETURN) {
164 ebt_print_error("--dnat-target RETURN not allowed on base chain");
165 return;
167 CLEAR_BASE_CHAIN_BIT;
168 if (((hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))
169 || strcmp(name, "nat")) &&
170 ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute"))) {
171 ebt_print_error("Wrong chain for dnat");
172 } else if (time == 0 && to_dest_supplied == 0)
173 ebt_print_error("No dnat address supplied");
176 static void print_s(const struct ebt_u_entry *entry,
177 const struct ebt_entry_target *target)
179 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
181 printf("--to-src ");
182 ebt_print_mac(natinfo->mac);
183 if (!(natinfo->target&NAT_ARP_BIT))
184 printf(" --snat-arp");
185 printf(" --snat-target %s", TARGET_NAME((natinfo->target|~EBT_VERDICT_BITS)));
188 static void print_d(const struct ebt_u_entry *entry,
189 const struct ebt_entry_target *target)
191 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
193 printf("--to-dst ");
194 ebt_print_mac(natinfo->mac);
195 printf(" --dnat-target %s", TARGET_NAME(natinfo->target));
198 static int compare(const struct ebt_entry_target *t1,
199 const struct ebt_entry_target *t2)
201 struct ebt_nat_info *natinfo1 = (struct ebt_nat_info *)t1->data;
202 struct ebt_nat_info *natinfo2 = (struct ebt_nat_info *)t2->data;
204 return !memcmp(natinfo1->mac, natinfo2->mac, sizeof(natinfo1->mac)) &&
205 natinfo1->target == natinfo2->target;
208 static struct ebt_u_target snat_target =
210 .name = "snat",
211 .size = sizeof(struct ebt_nat_info),
212 .help = print_help_s,
213 .init = init_s,
214 .parse = parse_s,
215 .final_check = final_check_s,
216 .print = print_s,
217 .compare = compare,
218 .extra_ops = opts_s,
221 static struct ebt_u_target dnat_target =
223 .name = "dnat",
224 .size = sizeof(struct ebt_nat_info),
225 .help = print_help_d,
226 .init = init_d,
227 .parse = parse_d,
228 .final_check = final_check_d,
229 .print = print_d,
230 .compare = compare,
231 .extra_ops = opts_d,
234 void _init(void)
236 ebt_register_target(&snat_target);
237 ebt_register_target(&dnat_target);