Tomato 1.25
[tomato.git] / release / src / linux / linux / net / ipv4 / netfilter / ip_nat_proto_esp.c
bloba985539e9db11373dfec917a0f785852f9b54144
1 /*
2 * ip_nat_proto_esp.c - Version 0.1
4 * NAT protocol helper module for ESP.
5 */
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/ip.h>
10 #include <linux/netfilter_ipv4/ip_nat.h>
11 #include <linux/netfilter_ipv4/ip_nat_rule.h>
12 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
13 #include <linux/netfilter_ipv4/ip_conntrack_proto_esp.h>
15 MODULE_LICENSE("GPL");
16 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
17 MODULE_DESCRIPTION("Netfilter NAT protocol helper module for ESP");
19 #if 0
20 //#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__": " format, ## args)
21 #define DEBUGP printk
22 #define DUMP_TUPLE_ESP(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x\n", \
23 NIPQUAD((x)->src.ip), ntohl((x)->src.u.esp.spi), \
24 NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.esp.spi))
25 #else
26 #define DUMP_TUPLE_ESP(x)
27 #define DEBUGP(x, args...)
28 #endif
30 /* is key in given range between min and max */
31 static int
32 esp_in_range(const struct ip_conntrack_tuple *tuple,
33 enum ip_nat_manip_type maniptype,
34 const union ip_conntrack_manip_proto *min,
35 const union ip_conntrack_manip_proto *max)
37 unsigned int spi;
38 DEBUGP("esp_in_range entry.\n");
39 return 0;
40 if (maniptype == IP_NAT_MANIP_SRC)
41 spi = tuple->src.u.esp.spi;
42 else
43 spi = tuple->dst.u.esp.spi;
45 DUMP_TUPLE_ESP(tuple);
47 return (ntohl(spi) >= ntohl(min->esp.spi) &&
48 ntohl(spi) <= ntohl(max->esp.spi));
52 /* generate unique tuple ... */
53 static int
54 esp_unique_tuple(struct ip_conntrack_tuple *tuple,
55 const struct ip_nat_range *range,
56 enum ip_nat_manip_type maniptype,
57 const struct ip_conntrack *conntrack)
59 u_int32_t min, i, range_size;
60 u_int32_t key = 0, *spi = NULL;
61 DEBUGP("esp_unique_tuple entry.\n");
62 return 1;
63 DUMP_TUPLE_ESP(tuple);
65 if (maniptype == IP_NAT_MANIP_SRC)
66 spi = &tuple->src.u.esp.spi;
67 else
68 spi = &tuple->dst.u.esp.spi;
70 /*range is to do fast search*/
71 if (! (range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
73 DEBUGP("NATing ESP (ct = %p)\n",conntrack);
74 min = 1;
75 range_size = 0xffffffff;
77 else
79 min = ntohl(range->min.esp.spi);
80 range_size = ntohl(range->max.esp.spi) - min + 1;
83 DEBUGP("min = %u, range_size = %u\n", min, range_size);
85 for (i = 0; i < range_size; i++, key++) {
86 *spi = htonl(min + key % range_size);
87 if (!ip_nat_used_tuple(tuple, conntrack))
88 return 1;
91 DEBUGP("%p: no NAT mapping\n", conntrack);
93 return 0;
96 /* manipulate a ESP packet according to maniptype */
97 static void
98 esp_manip_pkt(struct iphdr *iph, size_t len,
99 const struct ip_conntrack_manip *manip,
100 enum ip_nat_manip_type maniptype)
102 struct esp_hdr *esph = (struct esp_hdr *)((u_int32_t *)iph+iph->ihl);
103 u_int32_t *old_ip;
104 u_int32_t *old_spi =NULL;
105 u_int32_t sip = 0, dip =0,ret = 0;
106 DEBUGP("\n@@@@ %s @@@@\n", __FUNCTION__);
109 DEBUGP("dir =[%d] manip [%u.%u.%u.%u] spi[%x].\n "
110 "ip_header sip[%u.%u.%u.%u]dip[%u.%u.%u.%u].\n"
111 "spi[0x%x] seq[%u].\n",
112 maniptype,NIPQUAD(manip->ip),ntohl(manip->u.esp.spi),
113 NIPQUAD(iph->saddr),NIPQUAD(iph->daddr),ntohl(esph->spi),ntohl(esph->seq));
115 /*keep data to tuple struct*/
116 if (maniptype == IP_NAT_MANIP_SRC)
118 /* Get rid of dst ip / spi */
119 old_ip = &iph->daddr; //here orignal ip header
120 old_spi =&esph->spi;
122 else
124 ret = esp_packet_in(iph,&sip,&dip);
125 if (ret == NF_ACCEPT)
127 DEBUGP("found !! sip[%u.%u.%u.%u]dip[%u.%u.%u.%u]\n",
128 NIPQUAD(sip),NIPQUAD(dip));
129 old_ip = &dip; //here orignal ip header
130 old_spi = &esph->spi;
132 else
134 DEBUGP("Not found !! sip[%u.%u.%u.%u]dip[%u.%u.%u.%u]\n",
135 NIPQUAD(sip),NIPQUAD(dip));
136 /* Get rid of dst ip / spi */
137 old_ip = &iph->daddr; //here orignal ip header
138 old_spi = &esph->spi;
144 /* print out a nat tuple */
145 static unsigned int
146 esp_print(char *buffer,
147 const struct ip_conntrack_tuple *match,
148 const struct ip_conntrack_tuple *mask)
150 unsigned int len = 0;
151 DEBUGP("esp_print entry.\n");
152 DEBUGP("match.....\n");
153 DUMP_TUPLE_ESP(match);
154 DEBUGP("mask.....\n");
155 DUMP_TUPLE_ESP(mask);
156 DEBUGP("end.....\n\n");
157 return 0;
158 if (mask->dst.u.esp.spi)
159 len += sprintf(buffer + len, "dst spi=[0x%x]",
160 ntohl(match->dst.u.esp.spi));
162 if (mask->src.u.esp.spi)
163 len += sprintf(buffer + len, "src spi=0x%x ",
164 ntohl(match->src.u.esp.spi));
166 return len;
169 /* print a range of keys */
170 static unsigned int
171 esp_print_range(char *buffer, const struct ip_nat_range *range)
173 DEBUGP("esp_print_range entry.\n");
174 return 0;
175 if (range->min.esp.spi != 0
176 || range->max.esp.spi != 0xFFFFFFFF)
178 if (range->min.esp.spi == range->max.esp.spi)
179 return sprintf(buffer, "ESP SPI 0x%x ",
180 ntohl(range->min.esp.spi));
181 else
182 return sprintf(buffer, "ESP SPI 0x%u-0x%u ",
183 ntohl(range->min.esp.spi),
184 ntohl(range->max.esp.spi));
185 } else
186 return 0;
189 /* nat helper struct */
190 static struct ip_nat_protocol esp =
192 { NULL, NULL },
193 "ESP",
194 IPPROTO_ESP,
195 esp_manip_pkt,
196 esp_in_range,
197 esp_unique_tuple,
198 esp_print,
199 esp_print_range
202 static int __init init(void)
205 if (ip_nat_protocol_register(&esp))
206 return -EIO;
208 DEBUGP("init IP_nat_proto_esp register.\n");
209 return 0;
212 static void __exit fini(void)
214 DEBUGP("uninit IP_nat_proto_esp register.\n");
215 ip_nat_protocol_unregister(&esp);
218 module_init(init);
219 module_exit(fini);