K2.6 patches and update.
[tomato.git] / release / src / router / iptables / extensions / libipt_autofw.c
blob9c0d2b44885b64d369030f71bc8ceccc406b1b6a
1 /*
2 * Automatic port forwarding target. When this target is entered, a
3 * related connection to a port in the reply direction will be
4 * expected. This connection may be mapped to a different port.
6 * Copyright 2005, Broadcom Corporation
7 * All Rights Reserved.
8 *
9 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
10 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
11 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
12 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
14 * $Id: libipt_autofw.c,v 1.1.1.7 2005/03/07 07:31:14 kanki Exp $
17 /* Shared library add-on to iptables to add masquerade support. */
18 #include <stdio.h>
19 #include <netdb.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <getopt.h>
23 #include <iptables.h>
24 #include <linux/netfilter_ipv4/ip_tables.h>
25 #include <linux/netfilter_ipv4/ip_nat_rule.h>
26 #include <linux/netfilter_ipv4/ip_autofw.h>
28 /* Function which prints out usage message. */
29 static void
30 help(void)
32 printf(
33 "autofw v%s options:\n"
34 " --related-proto proto\n"
35 " Related protocol\n"
36 " --related-dport port[-port]\n"
37 " Related destination port range\n"
38 " --related-to port[-port]\n"
39 " Port range to map related destination port range to.\n\n",
40 IPTABLES_VERSION);
43 static struct option opts[] = {
44 { "related-proto", 1, 0, '1' },
45 { "related-dport", 1, 0, '2' },
46 { "related-to", 1, 0, '3' },
47 { 0 }
50 /* Initialize the target. */
51 static void
52 init(struct ipt_entry_target *t, unsigned int *nfcache)
54 /* Can't cache this */
55 *nfcache |= NFC_UNKNOWN;
58 /* Parses ports */
59 static void
60 parse_ports(const char *arg, u_int16_t *ports)
62 const char *dash;
63 int port;
65 port = atoi(arg);
66 if (port == 0 || port > 65535)
67 exit_error(PARAMETER_PROBLEM, "Port `%s' not valid\n", arg);
69 dash = strchr(arg, '-');
70 if (!dash)
71 ports[0] = ports[1] = htons(port);
72 else {
73 int maxport;
75 maxport = atoi(dash + 1);
76 if (maxport == 0 || maxport > 65535)
77 exit_error(PARAMETER_PROBLEM,
78 "Port `%s' not valid\n", dash+1);
79 if (maxport < port)
80 /* People are stupid. */
81 exit_error(PARAMETER_PROBLEM,
82 "Port range `%s' funky\n", arg);
83 ports[0] = htons(port);
84 ports[1] = htons(maxport);
89 /* Function which parses command options; returns true if it
90 ate an option */
91 static int
92 parse(int c, char **argv, int invert, unsigned int *flags,
93 const struct ipt_entry *entry,
94 struct ipt_entry_target **target)
96 struct ip_autofw_info *info = (struct ip_autofw_info *)(*target)->data;
98 switch (c) {
99 case '1':
100 if (!strcasecmp(optarg, "tcp"))
101 info->proto = IPPROTO_TCP;
102 else if (!strcasecmp(optarg, "udp"))
103 info->proto = IPPROTO_UDP;
104 else
105 exit_error(PARAMETER_PROBLEM,
106 "unknown protocol `%s' specified", optarg);
107 return 1;
109 case '2':
110 if (check_inverse(optarg, &invert, &optind, 0))
111 exit_error(PARAMETER_PROBLEM,
112 "Unexpected `!' after --related-dport");
114 parse_ports(optarg, info->dport);
115 return 1;
117 case '3':
118 if (check_inverse(optarg, &invert, &optind, 0))
119 exit_error(PARAMETER_PROBLEM,
120 "Unexpected `!' after --related-to");
122 parse_ports(optarg, info->to);
123 *flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
124 return 1;
126 default:
127 return 0;
131 /* Final check; don't care. */
132 static void final_check(unsigned int flags)
136 /* Prints out the targinfo. */
137 static void
138 print(const struct ipt_ip *ip,
139 const struct ipt_entry_target *target,
140 int numeric)
142 struct ip_autofw_info *info = (struct ip_autofw_info *)target->data;
144 printf("autofw ");
145 if (info->proto == IPPROTO_TCP)
146 printf("tcp ");
147 else if (info->proto == IPPROTO_UDP)
148 printf("udp ");
149 printf("dpt:%hu", ntohs(info->dport[0]));
150 if (ntohs(info->dport[1]) > ntohs(info->dport[0]))
151 printf("-%hu", ntohs(info->dport[1]));
152 printf(" ");
153 printf("to:%hu", ntohs(info->to[0]));
154 if (ntohs(info->to[1]) > ntohs(info->to[0]))
155 printf("-%hu", ntohs(info->to[1]));
156 printf(" ");
159 /* Saves the union ipt_targinfo in parsable form to stdout. */
160 static void
161 save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
163 struct ip_autofw_info *info = (struct ip_autofw_info *)target->data;
165 printf("--related-proto ");
166 if (info->proto == IPPROTO_TCP)
167 printf("tcp ");
168 else if (info->proto == IPPROTO_UDP)
169 printf("udp ");
170 printf("--related-dport %hu-%hu ", ntohs(info->dport[0]), ntohs(info->dport[1]));
171 printf("--related-to %hu-%hu ", ntohs(info->to[0]), ntohs(info->to[1]));
174 struct iptables_target autofw
175 = { NULL,
176 "autofw",
177 IPTABLES_VERSION,
178 IPT_ALIGN(sizeof(struct ip_autofw_info)),
179 IPT_ALIGN(sizeof(struct ip_autofw_info)),
180 &help,
181 &init,
182 &parse,
183 &final_check,
184 &print,
185 &save,
186 opts
189 void _init(void)
191 register_target(&autofw);