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