blob: 1d1e2361c9c51892fab44f45042ddc9b2e433030 [file] [log] [blame]
Martin Josefssonf419f752001-02-19 21:55:27 +00001#include <stdio.h>
2#include <netdb.h>
3#include <string.h>
4#include <stdlib.h>
5#include <getopt.h>
6#include <iptables.h>
7#include <linux/netfilter_ipv4/ip_tables.h>
8#include <linux/netfilter_ipv4/ip_nat_rule.h>
9
10#define BREAKUP_IP(x) (x)>>24, ((x)>>16) & 0xFF, ((x)>>8) & 0xFF, (x) & 0xFF
11
12/* Function which prints out usage message. */
13static void
14help(void)
15{
16 printf(
17"SAME v%s options:\n"
18" --to-source <ipaddr>-<ipaddr>\n"
19" Addresses to map source to.\n",
20NETFILTER_VERSION);
21}
22
23static struct option opts[] = {
24 { "to-source", 1, 0, '1' },
25 { 0 }
26};
27
28/* Initialize the target. */
29static void
30init(struct ipt_entry_target *t, unsigned int *nfcache)
31{
32 struct ip_nat_multi_range *mr = (struct ip_nat_multi_range *)t->data;
33
34 /* Actually, it's 0, but it's ignored at the moment. */
35 mr->rangesize = 1;
36
37 /* Can't cache this */
38 *nfcache |= NFC_UNKNOWN;
39}
40
41/* Parses range of IPs */
42static void
43parse_to(char *arg, struct ip_nat_range *range)
44{
45 char *dash;
46 struct in_addr *ip;
47
48 range->flags |= IP_NAT_RANGE_MAP_IPS;
49 dash = strchr(arg, '-');
50 if (dash)
51 *dash = '\0';
52 else
53 exit_error(PARAMETER_PROBLEM, "Bad IP range `%s'\n", arg);
54
55 ip = dotted_to_addr(arg);
56 if (!ip)
57 exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n",
58 arg);
59 range->min_ip = ip->s_addr;
60 ip = dotted_to_addr(dash+1);
61 if (!ip)
62 exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n",
63 dash+1);
64 range->max_ip = ip->s_addr;
65}
66
67/* Function which parses command options; returns true if it
68 ate an option */
69static int
70parse(int c, char **argv, int invert, unsigned int *flags,
71 const struct ipt_entry *entry,
72 struct ipt_entry_target **target)
73{
74 struct ip_nat_multi_range *mr
75 = (struct ip_nat_multi_range *)(*target)->data;
76
77 switch (c) {
78 case '1':
79 if (check_inverse(optarg, &invert))
80 exit_error(PARAMETER_PROBLEM,
81 "Unexpected `!' after --to-source");
82
83 parse_to(optarg, &mr->range[0]);
84 *flags = 1;
85 return 1;
86
87 default:
88 return 0;
89 }
90}
91
92/* Final check; need --to-dest. */
93static void final_check(unsigned int flags)
94{
95 if (!flags)
96 exit_error(PARAMETER_PROBLEM,
97 "BALANCE needs --to-source");
98}
99
100/* Prints out the targinfo. */
101static void
102print(const struct ipt_ip *ip,
103 const struct ipt_entry_target *target,
104 int numeric)
105{
106 struct ip_nat_multi_range *mr
107 = (struct ip_nat_multi_range *)target->data;
108 struct ip_nat_range *r = &mr->range[0];
109 struct in_addr a;
110
111 a.s_addr = r->min_ip;
112
113 printf("same %s", addr_to_dotted(&a));
114 a.s_addr = r->max_ip;
115 printf("-%s ", addr_to_dotted(&a));
116}
117
118/* Saves the union ipt_targinfo in parsable form to stdout. */
119static void
120save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
121{
122 struct ip_nat_multi_range *mr
123 = (struct ip_nat_multi_range *)target->data;
124 struct ip_nat_range *r = &mr->range[0];
125 struct in_addr a;
126
127 a.s_addr = r->min_ip;
128 printf("--to-source %s", addr_to_dotted(&a));
129 a.s_addr = r->max_ip;
130 printf("-%s ", addr_to_dotted(&a));
131}
132
133struct iptables_target same
134= { NULL,
135 "SAME",
136 NETFILTER_VERSION,
137 IPT_ALIGN(sizeof(struct ip_nat_multi_range)),
138 IPT_ALIGN(sizeof(struct ip_nat_multi_range)),
139 &help,
140 &init,
141 &parse,
142 &final_check,
143 &print,
144 &save,
145 opts
146};
147
148void _init(void)
149{
150 register_target(&same);
151}