2 * OLSR ad-hoc routing table management protocol
3 * Copyright (C) 2004 Andreas Tønnesen (andreto@ifi.uio.no)
5 * This file is part of olsr.org.
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.
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.
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
22 * $Id: tunnel.c,v 1.6 2004/11/03 10:00:11 kattemat Exp $
30 #include <sys/ioctl.h>
37 #include "../kernel_routes.h"
42 *Set up a IP in IP tunnel to a Internet gateway
44 *@param p the ip_tunnel_parm struct containing
47 *@return negative on error
51 add_ip_tunnel(struct ip_tunnel_parm *p)
56 /* Copy param for deletion */
57 memcpy(&ipt, p, sizeof(struct ip_tunnel_parm));
59 /* Create tunnel endpoint */
61 strcpy(ifr.ifr_name, "tunl0");
62 ifr.ifr_ifru.ifru_data = (void*)p;
64 err = ioctl(ioctl_s, SIOCCHGTUNNEL, &ifr);
67 perror("change IPv4 tunnel ioctl");
69 err = ioctl(ioctl_s, SIOCADDTUNNEL, &ifr);
71 perror("add IPv4 tunnel ioctl");
75 /* Set local address */
78 memcpy(&((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr,
82 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
85 strcpy(ifr.ifr_name, "tunl1");
87 if(ioctl(ioctl_s, SIOCSIFADDR, &ifr) < 0)
89 fprintf(stderr, "\tERROR setting tunnel address!\n\t%s\n",
94 /* Set local address */
96 memset(&ifr, 0, sizeof(struct ifreq));
99 memcpy(&((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr,
103 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
106 strcpy(ifr.ifr_name, "tunl1");
108 if(ioctl(ioctl_s, SIOCSIFADDR, &ifr) < 0)
110 fprintf(stderr, "\tERROR setting tunnel address!\n\t%s\n",
115 /* Set remote address */
117 memcpy(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr,
121 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
123 if(ioctl(ioctl_s, SIOCSIFDSTADDR, &ifr) < 0)
125 fprintf(stderr, "\tERROR setting tunnel remote address!\n\t%s\n",
131 set_flag("tunl1", IFF_POINTOPOINT);
133 add_tunnel_route((union olsr_ip_addr *)&p->iph.daddr);
135 /* Store the gateway address */
136 memcpy(&tnl_addr, &p->iph.daddr, ipsize);
137 inet_tnl_added = TRUE;
139 /* Enable tunnel forwarding for gateways */
140 enable_tunl_forwarding();
149 del_ip_tunnel(struct ip_tunnel_parm *p)
158 *Set up a source side endpoint for a IP in IP
161 *@param my_addr local address
162 *@param dst destination address
163 *@param if_index interface index to set up
169 set_up_source_tnl(union olsr_ip_addr *my_addr, union olsr_ip_addr *dst, int if_index)
171 struct ip_tunnel_parm itp;
173 memset(&itp, 0, sizeof(struct ip_tunnel_parm));
178 /* Name - CAN'T BE tunl0 !!!!!!!!!!!!!!!!!!! */
179 strcpy(itp.name, "tunl1");
183 /* Tunnel type IPinIP */
184 itp.iph.protocol = IPPROTO_IPIP;
185 /* Time to live - 255 */
189 /* Fragmentation - from iptools */
190 itp.iph.frag_off = htons(IP_DF);
192 itp.iph.saddr = (u_int32_t) my_addr->v4;
193 /* Destination address */
194 itp.iph.daddr = (u_int32_t) dst->v4;
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));
200 olsr_printf(1, "\tInterface: %d\n", if_index);
203 /* Add IPv4 tunnel */
214 *Set up a gateway side IP in IP tunnel with foregin
215 *endpoint address set to ANY.
217 *@return negative on error
221 set_up_gw_tunnel(union olsr_ip_addr *adr)
226 printf("Setting up a GW side IP tunnel...\n");
230 memset(&ifr, 0, sizeof(struct ifreq));
233 strcpy(ifr.ifr_name, "tunl0");
235 memcpy(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr,
239 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
241 printf("Setting GW tunnel address %s\n", sockaddr_to_string(&ifr.ifr_addr));
245 if(ioctl(ioctl_s, SIOCSIFADDR, &ifr) < 0)
247 fprintf(stderr, "\tERROR setting gw tunnel address!\n\t%s\n",
253 memset(&ifr, 0, sizeof(struct ifreq));
256 strcpy(ifr.ifr_name, "tunl0");
259 if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
261 fprintf(stderr,"ioctl (get interface flags)");
265 strcpy(ifr.ifr_name, "tunl0");
267 if(!(ifr.ifr_flags & IFF_UP & IFF_RUNNING))
270 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
272 if(ioctl(ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
274 fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
281 //enable_tunl_forwarding();
291 enable_tunl_forwarding()
295 char procfile[FILENAME_MAX];
297 strcpy(procfile, TUNL_PROC_FILE);
300 if ((proc_fwd=fopen(procfile, "r"))==NULL)
302 fprintf(stderr, "WARINING!! Could not open %s for writing!!\n", procfile);
308 ans = fgetc(proc_fwd);
312 printf("\nTunnel forwarding is enabeled\n");
316 if ((proc_fwd=fopen(procfile, "w"))==NULL)
318 fprintf(stderr, "Could not open %s for writing!\n", procfile);
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);