blob: 1f88ae2da3059ebb60c84d79cda938a337caecfd [file] [log] [blame]
Bart De Schuymer1abc55d2002-06-01 19:23:47 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/socket.h>
5#include <netinet/in.h>
Bart De Schuymer41830412002-06-05 19:41:28 +00006#include <netinet/ether.h>
Bart De Schuymer1abc55d2002-06-01 19:23:47 +00007#include <linux/netfilter_bridge/ebtables.h>
8#include <getopt.h>
9#include "../include/ebtables_u.h"
10#include <linux/netfilter_bridge/ebt_nat.h>
11
12extern char *standard_targets[NUM_STANDARD_TARGETS];
13
14int to_source_supplied, to_dest_supplied;
15
16#define NAT_S '1'
17#define NAT_D '1'
18#define NAT_S_TARGET '2'
19#define NAT_D_TARGET '2'
20static struct option opts_s[] =
21{
22 { "to-source" , required_argument, 0, NAT_S },
23 { "to-src" , required_argument, 0, NAT_S },
24 { "snat-target" , required_argument, 0, NAT_S_TARGET },
25 { 0 }
26};
27
28static struct option opts_d[] =
29{
30 { "to-destination", required_argument, 0, NAT_D },
31 { "to-dst" , required_argument, 0, NAT_D },
32 { "dnat-target" , required_argument, 0, NAT_D_TARGET },
33 { 0 }
34};
35
36static void print_help_s()
37{
38 printf(
39 "snat options:\n"
40 " --to-src address : MAC address to map source to\n"
41 " --snat-target target : ACCEPT, DROP or CONTINUE\n");
42}
43
44static void print_help_d()
45{
46 printf(
47 "dnat options:\n"
48 " --to-dst address : MAC address to map destination to\n"
49 " --dnat-target target : ACCEPT, DROP or CONTINUE\n");
50}
51
52static void init_s(struct ebt_entry_target *target)
53{
54 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
55
56 to_source_supplied = 0;
57 natinfo->target = EBT_ACCEPT;
58 return;
59}
60
61static void init_d(struct ebt_entry_target *target)
62{
63 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
64
65 to_dest_supplied = 0;
66 natinfo->target = EBT_ACCEPT;
67 return;
68}
69
70#define OPT_SNAT 0x01
71#define OPT_SNAT_TARGET 0x02
72static int parse_s(int c, char **argv, int argc,
73 const struct ebt_u_entry *entry, unsigned int *flags,
74 struct ebt_entry_target **target)
75{
76 int i;
77 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
Bart De Schuymer41830412002-06-05 19:41:28 +000078 struct ether_addr *addr;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000079
80 switch (c) {
81 case NAT_S:
82 check_option(flags, OPT_SNAT);
83 to_source_supplied = 1;
Bart De Schuymer41830412002-06-05 19:41:28 +000084 if (!(addr = ether_aton(optarg)))
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000085 print_error("Problem with specified to-source mac");
Bart De Schuymer41830412002-06-05 19:41:28 +000086 memcpy(natinfo->mac, addr, ETH_ALEN);
Bart De Schuymer1abc55d2002-06-01 19:23:47 +000087 break;
88 case NAT_S_TARGET:
89 check_option(flags, OPT_SNAT_TARGET);
90 for (i = 0; i < NUM_STANDARD_TARGETS; i++)
91 if (!strcmp(optarg, standard_targets[i])) {
92 natinfo->target = i;
93 break;
94 }
95 if (i == NUM_STANDARD_TARGETS)
96 print_error("Illegal --snat-target target");
97 break;
98 default:
99 return 0;
100 }
101 return 1;
102}
103
104#define OPT_DNAT 0x01
105#define OPT_DNAT_TARGET 0x02
106static int parse_d(int c, char **argv, int argc,
107 const struct ebt_u_entry *entry, unsigned int *flags,
108 struct ebt_entry_target **target)
109{
110 int i;
111 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
Bart De Schuymer41830412002-06-05 19:41:28 +0000112 struct ether_addr *addr;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000113
114 switch (c) {
115 case NAT_D:
116 check_option(flags, OPT_DNAT);
117 to_dest_supplied = 1;
Bart De Schuymer41830412002-06-05 19:41:28 +0000118 if (!(addr = ether_aton(optarg)))
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000119 print_error("Problem with specified "
120 "to-destination mac");
Bart De Schuymer41830412002-06-05 19:41:28 +0000121 memcpy(natinfo->mac, addr, ETH_ALEN);
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000122 break;
123 case NAT_D_TARGET:
124 check_option(flags, OPT_DNAT_TARGET);
125 for (i = 0; i < NUM_STANDARD_TARGETS; i++)
126 if (!strcmp(optarg, standard_targets[i])) {
127 natinfo->target = i;
128 break;
129 }
130 if (i == NUM_STANDARD_TARGETS)
131 print_error("Illegal --dnat-target target");
132 break;
133 default:
134 return 0;
135 }
136 return 1;
137}
138
139static void final_check_s(const struct ebt_u_entry *entry,
140 const struct ebt_entry_target *target, const char *name, unsigned int hook)
141{
142 if (hook != NF_BR_POST_ROUTING || strcmp(name, "nat"))
143 print_error("Wrong chain for snat");
144 if (to_source_supplied == 0)
145 print_error("No snat address supplied");
146}
147
148static void final_check_d(const struct ebt_u_entry *entry,
149 const struct ebt_entry_target *target, const char *name, unsigned int hook)
150{
151 if ( ((hook != NF_BR_PRE_ROUTING && hook != NF_BR_LOCAL_OUT) ||
152 strcmp(name, "nat")) &&
153 (hook != NF_BR_BROUTING || strcmp(name, "broute")) )
154 print_error("Wrong chain for dnat");
155 if (to_dest_supplied == 0)
156 print_error("No dnat address supplied");
157}
158
159static void print_s(const struct ebt_u_entry *entry,
160 const struct ebt_entry_target *target)
161{
162 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000163
164 printf("snat - to: ");
Bart De Schuymer41830412002-06-05 19:41:28 +0000165 printf("%s", ether_ntoa((struct ether_addr *)natinfo->mac));
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000166 printf(" --snat-target %s", standard_targets[natinfo->target]);
167}
168
169static void print_d(const struct ebt_u_entry *entry,
170 const struct ebt_entry_target *target)
171{
172 struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000173
174 printf("dnat - to: ");
Bart De Schuymer41830412002-06-05 19:41:28 +0000175 printf("%s", ether_ntoa((struct ether_addr *)natinfo->mac));
Bart De Schuymer1abc55d2002-06-01 19:23:47 +0000176 printf(" --dnat-target %s", standard_targets[natinfo->target]);
177}
178
179static int compare(const struct ebt_entry_target *t1,
180 const struct ebt_entry_target *t2)
181{
182 struct ebt_nat_info *natinfo1 = (struct ebt_nat_info *)t1->data;
183 struct ebt_nat_info *natinfo2 = (struct ebt_nat_info *)t2->data;
184
185
186 return !memcmp(natinfo1->mac, natinfo2->mac, sizeof(natinfo1->mac)) &&
187 natinfo1->target == natinfo2->target;
188}
189
190static struct ebt_u_target snat_target =
191{
192 EBT_SNAT_TARGET,
193 sizeof(struct ebt_nat_info),
194 print_help_s,
195 init_s,
196 parse_s,
197 final_check_s,
198 print_s,
199 compare,
200 opts_s,
201};
202
203static struct ebt_u_target dnat_target =
204{
205 EBT_DNAT_TARGET,
206 sizeof(struct ebt_nat_info),
207 print_help_d,
208 init_d,
209 parse_d,
210 final_check_d,
211 print_d,
212 compare,
213 opts_d,
214};
215
216static void _init(void) __attribute__ ((constructor));
217static void _init(void)
218{
219 register_target(&snat_target);
220 register_target(&dnat_target);
221}