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
32 *Bind a socket to a device
34 *@param sock the socket to bind
35 *@param dev_name name of the device
37 *@return negative if error
41 bind_socket_to_device(int sock, char *dev_name)
44 *Bind to device using the SO_BINDTODEVICE flag
46 olsr_printf(3, "Binding socket %d to device %s\n", sock, dev_name);
47 return setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, dev_name, strlen(dev_name)+1);
55 *Enable IP forwarding.
56 *Just writing "1" to the /proc/sys/net/ipv4/ip_forward
57 *if using IPv4 or /proc/sys/net/ipv6/conf/all/forwarding
59 *Could probably drop the check for
60 *"0" here and write "1" anyways.
62 *@param version IP version.
64 *@return 1 on sucess 0 on failiure
67 enable_ip_forwarding(int version)
70 char procfile[FILENAME_MAX];
72 if(version == AF_INET)
74 strcpy(procfile, "/proc/sys/net/ipv4/ip_forward");
77 if(version == AF_INET6)
79 strcpy(procfile, "/proc/sys/net/ipv6/conf/all/forwarding");
85 if ((proc_fwd=fopen(procfile, "r"))==NULL)
88 if(version == AF_INET)
89 fprintf(stderr, "WARNING! Could not open the %s file to check/enable IP forwarding!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n", procfile);
92 fprintf(stderr, "WARNING! Could not open the %s file to check/enable IP forwarding!\nAre you using the procfile filesystem?\nDoes your system support IPv6?\nI will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n", procfile);
100 orig_fwd_state = fgetc(proc_fwd);
102 if(orig_fwd_state == '1')
104 olsr_printf(3, "\nIP forwarding is enabled on this system\n");
108 if ((proc_fwd=fopen(procfile, "w"))==NULL)
110 fprintf(stderr, "Could not open %s for writing!\n", procfile);
111 fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that IP forwarding is enabeled!\n\n");
117 syslog(LOG_INFO, "Writing \"1\" to %s\n", procfile);
118 fputs("1", proc_fwd);
131 *@return 1 on sucess 0 on failiure
134 disable_redirects(char *if_name, int index, int version)
137 char procfile[FILENAME_MAX];
139 if(version == AF_INET6)
142 /* Generate the procfile name */
143 sprintf(procfile, REDIRECT_PROC, if_name);
146 if((proc_redirect = fopen(procfile, "r")) == NULL)
148 fprintf(stderr, "WARNING! Could not open the %s file to check/disable ICMP redirects!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that ICMP redirects are disabled!\n\n", procfile);
155 nic_states[index].redirect = fgetc(proc_redirect);
156 fclose(proc_redirect);
160 if ((proc_redirect = fopen(procfile, "w"))==NULL)
162 fprintf(stderr, "Could not open %s for writing!\n", procfile);
163 fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that ICMP redirect is disabeled!\n\n");
169 syslog(LOG_INFO, "Writing \"0\" to %s", procfile);
170 fputs("0", proc_redirect);
172 fclose(proc_redirect);
181 *@return 1 on sucess 0 on failiure
184 deactivate_spoof(char *if_name, int index, int version)
187 char procfile[FILENAME_MAX];
189 if(version == AF_INET6)
193 /* Generate the procfile name */
194 sprintf(procfile, SPOOF_PROC, if_name);
197 if((proc_spoof = fopen(procfile, "r")) == NULL)
199 fprintf(stderr, "WARNING! Could not open the %s file to check/disable the IP spoof filter!\nAre you using the procfile filesystem?\nDoes your system support IPv4?\nI will continue(in 3 sec) - but you should mannually ensure that IP spoof filtering is disabled!\n\n", procfile);
206 nic_states[index].spoof = fgetc(proc_spoof);
211 if ((proc_spoof = fopen(procfile, "w")) == NULL)
213 fprintf(stderr, "Could not open %s for writing!\n", procfile);
214 fprintf(stderr, "I will continue(in 3 sec) - but you should mannually ensure that IP spoof filtering is disabeled!\n\n");
220 syslog(LOG_INFO, "Writing \"0\" to %s", procfile);
221 fputs("0", proc_spoof);
231 *Resets the spoof filter and ICMP redirect settings
235 restore_settings(int version)
238 char procfile[FILENAME_MAX];
239 struct interface *ifs;
241 olsr_printf(1, "Restoring network state\n");
243 /* Restore IP forwarding to "off" */
244 if(orig_fwd_state == '0')
246 if(version == AF_INET)
248 strcpy(procfile, "/proc/sys/net/ipv4/ip_forward");
250 else if(version == AF_INET6)
252 strcpy(procfile, "/proc/sys/net/ipv6/conf/all/forwarding");
255 if ((proc_fd = fopen(procfile, "w")) == NULL)
257 fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile);
261 syslog(LOG_INFO, "Resetting %s to %c\n", procfile, orig_fwd_state);
262 fputc(orig_fwd_state, proc_fd);
268 if(version == AF_INET6)
271 for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
275 /* Generate the procfile name */
276 sprintf(procfile, REDIRECT_PROC, ifs->int_name);
278 if ((proc_fd = fopen(procfile, "w")) == NULL)
280 fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile);
284 syslog(LOG_INFO, "Resetting %s to %c\n", procfile, nic_states[ifs->if_nr].redirect);
286 fputc(nic_states[ifs->if_nr].redirect, proc_fd);
293 /* Generate the procfile name */
294 sprintf(procfile, SPOOF_PROC, ifs->int_name);
296 if ((proc_fd = fopen(procfile, "w")) == NULL)
298 fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procfile);
302 syslog(LOG_INFO, "Resetting %s to %c\n", procfile, nic_states[ifs->if_nr].spoof);
304 fputc(nic_states[ifs->if_nr].spoof, proc_fd);
316 *Creates a nonblocking broadcast socket.
317 *@param sa sockaddr struct. Used for bind(2).
318 *@return the FD of the socket or -1 on error.
321 getsocket(struct sockaddr *sa, int bufspace, char *int_name)
323 struct sockaddr_in *sin=(struct sockaddr_in *)sa;
328 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
331 syslog(LOG_ERR, "socket: %m");
338 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
340 perror("setsockopt");
341 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
347 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
349 perror("SO_REUSEADDR failed");
357 for (on = bufspace; ; on -= 1024)
359 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
360 &on, sizeof (on)) == 0)
364 perror("setsockopt");
365 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
375 * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!!
379 if(bind_socket_to_device(sock, int_name) < 0)
381 fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
382 syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
387 if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0)
390 syslog(LOG_ERR, "bind: %m");
396 *One should probably fetch the flags first
399 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
400 syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
407 *Creates a nonblocking IPv6 socket
408 *@param sin sockaddr_in6 struct. Used for bind(2).
409 *@return the FD of the socket or -1 on error.
412 getsocket6(struct sockaddr_in6 *sin, int bufspace, char *int_name)
418 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
421 syslog(LOG_ERR, "socket: %m");
427 //#ifdef SO_BROADCAST
429 if (setsockopt(sock, SOL_SOCKET, SO_MULTICAST, &on, sizeof (on)) < 0)
431 perror("setsockopt");
432 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
443 for (on = bufspace; ; on -= 1024)
445 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
446 &on, sizeof (on)) == 0)
450 perror("setsockopt");
451 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
459 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
461 perror("SO_REUSEADDR failed");
467 * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!!
471 if(bind_socket_to_device(sock, int_name) < 0)
473 fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
474 syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
479 if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0)
482 syslog(LOG_ERR, "bind: %m");
488 *One should probably fetch the flags first
491 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
492 syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");