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