1 /* Shared library add-on to iptables to add masquerade support. */
8 #include <linux/netfilter_ipv4/ip_tables.h>
9 #include <linux/netfilter/nf_nat.h>
11 /* Function which prints out usage message. */
12 static void MASQUERADE_help(void)
15 "MASQUERADE target options:\n"
16 " --to-ports <port>[-<port>]\n"
17 " Port (range) to map to.\n"
19 " Randomize source port.\n");
22 static const struct option MASQUERADE_opts[] = {
23 { "to-ports", 1, NULL, '1' },
24 { "random", 0, NULL, '2' },
28 /* Initialize the target. */
29 static void MASQUERADE_init(struct xt_entry_target *t)
31 struct ip_nat_multi_range *mr = (struct ip_nat_multi_range *)t->data;
33 /* Actually, it's 0, but it's ignored at the moment. */
40 parse_ports(const char *arg, struct ip_nat_multi_range *mr)
45 mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
48 if (port <= 0 || port > 65535)
49 exit_error(PARAMETER_PROBLEM, "Port `%s' not valid\n", arg);
51 dash = strchr(arg, '-');
53 mr->range[0].min.tcp.port
54 = mr->range[0].max.tcp.port
59 maxport = atoi(dash + 1);
60 if (maxport == 0 || maxport > 65535)
61 exit_error(PARAMETER_PROBLEM,
62 "Port `%s' not valid\n", dash+1);
64 /* People are stupid. Present reader excepted. */
65 exit_error(PARAMETER_PROBLEM,
66 "Port range `%s' funky\n", arg);
67 mr->range[0].min.tcp.port = htons(port);
68 mr->range[0].max.tcp.port = htons(maxport);
72 /* Function which parses command options; returns true if it
74 static int MASQUERADE_parse(int c, char **argv, int invert, unsigned int *flags,
75 const void *e, struct xt_entry_target **target)
77 const struct ipt_entry *entry = e;
79 struct ip_nat_multi_range *mr
80 = (struct ip_nat_multi_range *)(*target)->data;
82 if (entry->ip.proto == IPPROTO_TCP
83 || entry->ip.proto == IPPROTO_UDP
84 || entry->ip.proto == IPPROTO_ICMP)
92 exit_error(PARAMETER_PROBLEM,
93 "Need TCP or UDP with port specification");
95 if (check_inverse(optarg, &invert, NULL, 0))
96 exit_error(PARAMETER_PROBLEM,
97 "Unexpected `!' after --to-ports");
99 parse_ports(optarg, mr);
103 mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
111 /* Prints out the targinfo. */
113 MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
116 struct ip_nat_multi_range *mr
117 = (struct ip_nat_multi_range *)target->data;
118 struct ip_nat_range *r = &mr->range[0];
120 if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
121 printf("masq ports: ");
122 printf("%hu", ntohs(r->min.tcp.port));
123 if (r->max.tcp.port != r->min.tcp.port)
124 printf("-%hu", ntohs(r->max.tcp.port));
128 if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
132 /* Saves the union ipt_targinfo in parsable form to stdout. */
134 MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
136 struct ip_nat_multi_range *mr
137 = (struct ip_nat_multi_range *)target->data;
138 struct ip_nat_range *r = &mr->range[0];
140 if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
141 printf("--to-ports %hu", ntohs(r->min.tcp.port));
142 if (r->max.tcp.port != r->min.tcp.port)
143 printf("-%hu", ntohs(r->max.tcp.port));
147 if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
151 static struct xtables_target masquerade_tg_reg = {
152 .name = "MASQUERADE",
153 .version = XTABLES_VERSION,
155 .size = XT_ALIGN(sizeof(struct ip_nat_multi_range)),
156 .userspacesize = XT_ALIGN(sizeof(struct ip_nat_multi_range)),
157 .help = MASQUERADE_help,
158 .init = MASQUERADE_init,
159 .parse = MASQUERADE_parse,
160 .print = MASQUERADE_print,
161 .save = MASQUERADE_save,
162 .extra_opts = MASQUERADE_opts,
167 xtables_register_target(&masquerade_tg_reg);