Added CVS Id to all C and haeder files
[olsrd.git] / src / linux / tunnel.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of olsr.org.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: tunnel.c,v 1.5 2004/09/21 19:08:58 kattemat Exp $
23  *
24  */
25
26
27 #include <net/if.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/ioctl.h>
31
32 #include "tunnel.h"
33 #include "../defs.h"
34 #include "../olsr.h"
35 #include "../ifnet.h"
36
37 #include "../kernel_routes.h"
38
39 #include <errno.h>
40
41 /**
42  *Set up a IP in IP tunnel to a Internet gateway
43  *
44  *@param p the ip_tunnel_parm struct containing 
45  *the tunnel info
46  *
47  *@return negative on error
48  */
49
50 int
51 add_ip_tunnel(struct ip_tunnel_parm *p)
52 {
53   struct ifreq ifr;
54   int err;
55   
56   /* Copy param for deletion */
57   memcpy(&ipt, p, sizeof(struct ip_tunnel_parm));
58   
59   /* Create tunnel endpoint */
60   
61   strcpy(ifr.ifr_name, "tunl0");
62   ifr.ifr_ifru.ifru_data = (void*)p;
63   
64   err = ioctl(ioctl_s, SIOCCHGTUNNEL, &ifr);
65   if (err)
66     {
67       perror("change IPv4 tunnel ioctl");
68       /* Try new tunnel */
69       err = ioctl(ioctl_s, SIOCADDTUNNEL, &ifr);
70       if(err)
71         perror("add IPv4 tunnel ioctl");
72     }
73   
74   
75   /* Set local address */
76   
77   
78   memcpy(&((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr, 
79          &main_addr, 
80          ipsize);
81   
82   ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET; 
83   
84   
85   strcpy(ifr.ifr_name, "tunl1");
86   
87   if(ioctl(ioctl_s, SIOCSIFADDR, &ifr) < 0)
88     {
89       fprintf(stderr, "\tERROR setting tunnel address!\n\t%s\n", 
90               strerror(errno));
91     }
92   
93   
94   /* Set local address */
95   
96   memset(&ifr, 0, sizeof(struct ifreq));
97   
98   
99   memcpy(&((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr, 
100          &p->iph.saddr, 
101          ipsize);
102   
103   ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET; 
104   
105   
106   strcpy(ifr.ifr_name, "tunl1");
107   
108   if(ioctl(ioctl_s, SIOCSIFADDR, &ifr) < 0)
109     {
110       fprintf(stderr, "\tERROR setting tunnel address!\n\t%s\n", 
111               strerror(errno));
112     }
113   
114   
115   /* Set remote address */
116   
117   memcpy(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, 
118          &p->iph.daddr, 
119          ipsize);
120   
121   ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET; 
122   
123   if(ioctl(ioctl_s, SIOCSIFDSTADDR, &ifr) < 0)
124     {
125       fprintf(stderr, "\tERROR setting tunnel remote address!\n\t%s\n", 
126               strerror(errno));
127     }
128   
129   
130   /* Set up */
131   set_flag("tunl1", IFF_POINTOPOINT);
132   
133   add_tunnel_route((union olsr_ip_addr *)&p->iph.daddr);
134   
135   /* Store the gateway address */
136   memcpy(&tnl_addr, &p->iph.daddr, ipsize);
137   inet_tnl_added = 1;
138   
139   /* Enable tunnel forwarding for gateways */
140   enable_tunl_forwarding();
141   
142   return err;
143 }
144
145
146
147
148 int
149 del_ip_tunnel(struct ip_tunnel_parm *p)
150 {
151
152
153   return 1;
154 }
155
156
157 /**
158  *Set up a source side endpoint for a IP in IP
159  *tunnel
160  *
161  *@param my_addr local address
162  *@param dst destination address
163  *@param if_index interface index to set up
164  *
165  *@return nada
166  */
167
168 void
169 set_up_source_tnl(union olsr_ip_addr *my_addr, union olsr_ip_addr *dst, int if_index)
170 {
171   struct ip_tunnel_parm itp;
172   
173   memset(&itp, 0, sizeof(struct ip_tunnel_parm));
174   
175   /*
176    * Tunnel info 
177    */
178   /* Name - CAN'T BE tunl0 !!!!!!!!!!!!!!!!!!! */
179   strcpy(itp.name, "tunl1");
180   /* IP version */
181   itp.iph.version = 4;
182   itp.iph.ihl = 5;
183   /* Tunnel type IPinIP */
184   itp.iph.protocol = IPPROTO_IPIP;
185   /* Time to live - 255 */
186   itp.iph.ttl = 255;
187   /* TOS - 1 */
188   itp.iph.tos = 1;
189   /* Fragmentation - from iptools */
190   itp.iph.frag_off = htons(IP_DF);
191   /* Source address */
192   itp.iph.saddr = (u_int32_t) my_addr->v4;
193   /* Destination address */
194   itp.iph.daddr = (u_int32_t) dst->v4;
195
196   olsr_printf(1, "\tsource   : %s\n", ip_to_string(&itp.iph.saddr));
197   olsr_printf(1, "\tdest     : %s\n", ip_to_string(&itp.iph.daddr));
198
199   /* Interface */
200   olsr_printf(1, "\tInterface: %d\n", if_index);
201   itp.link = if_index;
202
203   /* Add IPv4 tunnel */
204   add_ip_tunnel(&itp);
205
206   return;
207 }
208
209
210
211
212
213 /**
214  *Set up a gateway side IP in IP tunnel with foregin
215  *endpoint address set to ANY.
216  *
217  *@return negative on error
218  */
219
220 int
221 set_up_gw_tunnel(union olsr_ip_addr *adr)
222 {
223
224   struct ifreq ifr;
225
226   printf("Setting up a GW side IP tunnel...\n");
227
228   gw_tunnel = 1;
229
230   memset(&ifr, 0, sizeof(struct ifreq));
231
232   /* Set address */
233   strcpy(ifr.ifr_name, "tunl0");
234     
235   memcpy(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, 
236          adr, 
237          ipsize);
238   
239   ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET; 
240   
241   printf("Setting GW tunnel address %s\n", sockaddr_to_string(&ifr.ifr_addr));
242
243   /* Set address */
244
245   if(ioctl(ioctl_s, SIOCSIFADDR, &ifr) < 0)
246     {
247       fprintf(stderr, "\tERROR setting gw tunnel address!\n\t%s\n", 
248               strerror(errno));
249     }
250
251   /* Set tunnel UP */
252
253   memset(&ifr, 0, sizeof(struct ifreq));
254
255   /* Set address */
256   strcpy(ifr.ifr_name, "tunl0");
257
258   /* Get flags */
259   if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
260     {
261       fprintf(stderr,"ioctl (get interface flags)");
262       return -1;
263     }
264
265   strcpy(ifr.ifr_name, "tunl0");
266
267    if(!(ifr.ifr_flags & IFF_UP & IFF_RUNNING))
268     {
269       /* Add UP */
270       ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
271       /* Set flags + UP */
272       if(ioctl(ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
273         {
274           fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
275           return -1;
276         }
277     }
278    
279
280    /* FIX THIS !!! */
281    //enable_tunl_forwarding();
282
283    return 1;
284 }
285
286
287
288
289
290 int
291 enable_tunl_forwarding()
292 {
293   FILE *proc_fwd;
294   int ans = 0;
295   char procfile[FILENAME_MAX];
296
297   strcpy(procfile, TUNL_PROC_FILE);
298
299
300   if ((proc_fwd=fopen(procfile, "r"))==NULL)
301     {
302       fprintf(stderr, "WARINING!! Could not open %s for writing!!\n", procfile);      
303       return 0;
304     }
305   
306   else
307     {
308       ans = fgetc(proc_fwd);
309       fclose(proc_fwd);
310       if(ans == '1')
311         {
312           printf("\nTunnel forwarding is enabeled\n");
313         }
314       else
315         {
316           if ((proc_fwd=fopen(procfile, "w"))==NULL)
317             {
318               fprintf(stderr, "Could not open %s for writing!\n", procfile);
319               return 0;
320             }
321           else
322             {
323               printf("Enabling TUNNEL-forwarding by writing \"1\" to the %s file\nThis file will not be restored to its original state!\n", procfile);
324               fputs("1", proc_fwd);
325             }
326           fclose(proc_fwd);
327
328         }
329     }
330   return 1;
331       
332 }
333
334
335
336
337
338
339
340
341
342