# BRCM_VERSION=3
[bcm963xx.git] / kernel / linux / net / ipv4 / netfilter / ip_nat_proto_esp.c
1 /*
2 <:copyright-gpl
3  Copyright 2002 Broadcom Corp. All Rights Reserved.
4
5  This program is free software; you can distribute it and/or modify it
6  under the terms of the GNU General Public License (Version 2) as
7  published by the Free Software Foundation.
8
9  This program is distributed in the hope it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  for more details.
13
14  You should have received a copy of the GNU General Public License along
15  with this program; if not, write to the Free Software Foundation, Inc.,
16  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 :>
18 */
19 /******************************************************************************
20 //
21 //  Filename:       ip_nat_proto_esp.c
22 //  Author:         Pavan Kumar
23 //  Creation Date:  05/27/04
24 //
25 //  Description:
26 //      Implements the ESP ALG connectiontracking.
27 //
28 *****************************************************************************/
29 #include <linux/types.h>
30 #include <linux/init.h>
31 #include <linux/netfilter.h>
32 #include <linux/ip.h>
33 #include <linux/if.h>
34
35 #include <linux/netfilter_ipv4/ip_nat.h>
36 #include <linux/netfilter_ipv4/ip_nat_rule.h>
37 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
38
39 #define TEMP_SPI_START 1500
40
41 static int
42 esp_in_range(const struct ip_conntrack_tuple *tuple,
43              enum ip_nat_manip_type maniptype,
44              const union ip_conntrack_manip_proto *min,
45              const union ip_conntrack_manip_proto *max)
46 {
47         //printk ( KERN_DEBUG "%s:%s spi %hu dpi %hu sip %u.%u.%u.%u dip %u.%u.%u.%u\n",
48         //       __FILE__, __FUNCTION__, ntohs(tuple->src.u.esp.spi),
49         //       ntohs(tuple->dst.u.esp.spi), NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip) );
50         return 1;
51 }
52
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)
58 {
59         static u_int16_t id = 0, *tspi;
60         unsigned int range_size = 0x40;
61         unsigned int i;
62
63         //printk ( KERN_DEBUG "%s:%s manitype %d sip %u.%u.%u.%u dip %u.%u.%u.%u"
64         //         " sspi %u dspi %u\n", __FILE__, __FUNCTION__, maniptype,
65         //         NIPQUAD(tuple->src.ip),
66         //         NIPQUAD(tuple->dst.ip), tuple->src.u.esp.spi, tuple->dst.u.esp.spi );
67         /* If no range specified... */
68         if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
69                 range_size = 0x40;
70
71         if ( maniptype == IP_NAT_MANIP_SRC ) {
72                 tspi = &tuple->src.u.esp.spi;
73         } else {
74                 tspi = &tuple->dst.u.esp.spi;
75         }
76
77         for (i = 0; i < range_size; i++, id++) {
78                 *tspi = TEMP_SPI_START + (id % range_size);
79                 if (!ip_nat_used_tuple(tuple, conntrack))
80                         return 1;
81         }
82
83         return 0;
84 }
85
86 static int
87 esp_manip_pkt(struct sk_buff **pskb,
88               unsigned int hdroff,      
89               const struct ip_conntrack_manip *manip,
90               enum ip_nat_manip_type maniptype)
91 {
92         u_int32_t oldip;
93         //struct esphdr *hdr = (void *)(*pskb)->data + hdroff;
94
95         if (maniptype == IP_NAT_MANIP_SRC) {
96                 /* Get rid of src ip and src pt */
97                 oldip = (*pskb)->nh.iph->saddr;
98                 //printk ( KERN_DEBUG "%s:%s MANIP_SRC oldip %u.%u.%u.%u daddr"
99                 //         " %u.%u.%u.%u manip %u.%u.%u.%u spi 0x%x seq 0x%x\n",
100                 //         __FILE__, __FUNCTION__, NIPQUAD(oldip), NIPQUAD(iph->daddr),
101                 //         NIPQUAD(manip->ip), ntohl(hdr->spi),
102                 //         ntohl(hdr->seq) );
103         } else {
104                 /* Get rid of dst ip and dst pt */
105                 oldip = (*pskb)->nh.iph->daddr;
106                 //printk ( KERN_DEBUG "%s:%s MANIP_DST oldip %u.%u.%u.%u saddr"
107                 //         " %u.%u.%u.%u manip %u.%u.%u.%u spi 0x%x seq 0x%x\n",
108                 //         __FILE__, __FUNCTION__, NIPQUAD(oldip), NIPQUAD(iph->saddr),
109                 //         NIPQUAD(manip->ip), ntohl(hdr->spi),
110                 //         ntohl(hdr->seq) );
111         }
112         return 1;
113 }
114
115 static unsigned int
116 esp_print(char *buffer,
117           const struct ip_conntrack_tuple *match,
118           const struct ip_conntrack_tuple *mask)
119 {
120         unsigned int len = 0;
121
122         //printk ( KERN_DEBUG "%s:%s mask spi %u dpi %u\n",
123         //       __FILE__, __FUNCTION__, mask->src.u.esp.spi, mask->dst.u.esp.spi );
124         if (mask->src.u.esp.spi)
125                 len += sprintf(buffer + len, "spi=%u ",
126                                ntohs(match->src.u.esp.spi));
127
128         return len;
129 }
130
131 static unsigned int
132 esp_print_range(char *buffer, const struct ip_nat_range *range)
133 {
134         //printk ( KERN_DEBUG "%s:%s min %u max %u\n", __FILE__, __FUNCTION__,
135         //       ntohs(range->min.esp.spi), ntohs(range->max.esp.spi) );
136         if (range->min.esp.spi != 0 ) {
137                 return sprintf(buffer, "port %u ",
138                                ntohs(range->min.esp.spi));
139         } else if ( range->max.esp.spi != 0 ) {
140                 return sprintf(buffer, "ports %u-%u ",
141                                ntohs(range->min.esp.spi),
142                                ntohs(range->max.esp.spi));
143         }
144         else return 0;
145 }
146
147 struct ip_nat_protocol ip_nat_protocol_esp
148 = { { NULL, NULL }, "ESP", IPPROTO_ESP,
149     esp_manip_pkt,
150     esp_in_range,
151     esp_unique_tuple,
152     esp_print,
153     esp_print_range
154 };