2 * ip_nat_proto_esp.c - Version 0.1
4 * NAT protocol helper module for ESP.
7 #include <linux/config.h>
8 #include <linux/module.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");
20 //#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__": " format, ## args)
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))
26 #define DUMP_TUPLE_ESP(x)
27 #define DEBUGP(x, args...)
30 /* is key in given range between min and max */
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
)
38 DEBUGP("esp_in_range entry.\n");
40 if (maniptype
== IP_NAT_MANIP_SRC
)
41 spi
= tuple
->src
.u
.esp
.spi
;
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 ... */
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");
63 DUMP_TUPLE_ESP(tuple
);
65 if (maniptype
== IP_NAT_MANIP_SRC
)
66 spi
= &tuple
->src
.u
.esp
.spi
;
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
);
75 range_size
= 0xffffffff;
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
))
91 DEBUGP("%p: no NAT mapping\n", conntrack
);
96 /* manipulate a ESP packet according to maniptype */
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
);
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
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
;
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 */
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");
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
));
169 /* print a range of keys */
171 esp_print_range(char *buffer
, const struct ip_nat_range
*range
)
173 DEBUGP("esp_print_range entry.\n");
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
));
182 return sprintf(buffer
, "ESP SPI 0x%u-0x%u ",
183 ntohl(range
->min
.esp
.spi
),
184 ntohl(range
->max
.esp
.spi
));
189 /* nat helper struct */
190 static struct ip_nat_protocol esp
=
202 static int __init
init(void)
205 if (ip_nat_protocol_register(&esp
))
208 DEBUGP("init IP_nat_proto_esp register.\n");
212 static void __exit
fini(void)
214 DEBUGP("uninit IP_nat_proto_esp register.\n");
215 ip_nat_protocol_unregister(&esp
);