Added netBSD patch and chenged so that the help message is shown if the target OS...
[olsrd.git] / src / bsd / net.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: net.c,v 1.7 2004/11/21 10:50:52 kattemat Exp $
40  */
41
42 #include "../defs.h"
43 #include "../net_os.h"
44 #include "net.h"
45
46 #include <sys/sysctl.h>
47
48 static int ignore_redir;
49 static int send_redir;
50 static int gateway;
51
52 static int first_time = 1;
53
54 static int set_sysctl_int(char *name, int new)
55 {
56   int old;
57   unsigned int len = sizeof (old);
58
59   if (sysctlbyname(name, &old, &len, &new, sizeof (new)) < 0)
60     return -1;
61
62   return old;
63 }
64
65 int enable_ip_forwarding(int version)
66 {
67   char *name;
68
69   if (olsr_cnf->ip_version == AF_INET)
70     name = "net.inet.ip.forwarding";
71
72   else
73     name = "net.inet6.ip6.forwarding";
74
75   gateway = set_sysctl_int(name, 1);
76
77   if (gateway < 0)
78     {
79       fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually. Continuing in 3 seconds...\n");
80       sleep(3);
81     }
82
83   return 1;
84 }
85
86 int disable_redirects(char *if_name, int index, int version)
87 {
88   char *name;
89
90   // this function gets called for each interface olsrd uses; however,
91   // FreeBSD can only globally control ICMP redirects, and not on a
92   // per-interface basis; hence, only disable ICMP redirects on the first
93   // invocation
94
95   if (first_time == 0)
96     return 1;
97
98   first_time = 0;
99
100   // do not accept ICMP redirects
101
102   if (olsr_cnf->ip_version == AF_INET)
103     name = "net.inet.icmp.drop_redirect";
104
105   else
106     name = "net.inet6.icmp6.drop_redirect";
107
108   ignore_redir = set_sysctl_int(name, 1);
109
110   if (ignore_redir < 0)
111     {
112       fprintf(stderr, "Cannot disable incoming ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
113       sleep(3);
114     }
115
116   // do not send ICMP redirects
117
118   if (olsr_cnf->ip_version == AF_INET)
119     name = "net.inet.ip.redirect";
120
121   else
122     name = "net.inet6.ip6.redirect";
123
124   send_redir = set_sysctl_int(name, 0);
125
126   if (send_redir < 0)
127     {
128       fprintf(stderr, "Cannot disable outgoing ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
129       sleep(3);
130     }
131
132   return 1;
133 }
134
135 int deactivate_spoof(char *if_name, int index, int version)
136 {
137   return 1;
138 }
139
140 int restore_settings(int version)
141 {
142   char *name;
143
144   // reset IP forwarding
145
146   if (olsr_cnf->ip_version == AF_INET)
147     name = "net.inet.ip.forwarding";
148
149   else
150     name = "net.inet6.ip6.forwarding";
151
152   set_sysctl_int(name, gateway);
153
154   // reset incoming ICMP redirects
155
156   if (olsr_cnf->ip_version == AF_INET)
157     name = "net.inet.icmp.drop_redirect";
158
159   else
160     name = "net.inet6.icmp6.drop_redirect";
161
162   set_sysctl_int(name, ignore_redir);
163
164   // reset outgoing ICMP redirects
165
166   if (olsr_cnf->ip_version == AF_INET)
167     name = "net.inet.ip.redirect";
168
169   else
170     name = "net.inet6.ip6.redirect";
171
172   set_sysctl_int(name, send_redir);
173
174   return 1;
175 }
176
177 int
178 getsocket(struct sockaddr *sa, int bufspace, char *int_name)
179 {
180   struct sockaddr_in *sin = (struct sockaddr_in *)sa;
181   int sock, on = 1;
182
183   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
184     {
185       perror("socket");
186       syslog(LOG_ERR, "socket: %m");
187       return (-1);
188     }
189
190   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
191     {
192       perror("setsockopt");
193       syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
194       close(sock);
195       return (-1);
196     }
197
198   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
199     {
200       perror("SO_REUSEADDR failed");
201       return (-1);
202     }
203
204   for (on = bufspace; ; on -= 1024) 
205     {
206       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
207                      &on, sizeof (on)) == 0)
208         break;
209       if (on <= 8*1024) 
210         {
211           perror("setsockopt");
212           syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
213           break;
214         }
215     }
216
217   if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) 
218     {
219       perror("bind");
220       syslog(LOG_ERR, "bind: %m");
221       close(sock);
222       return (-1);
223     }
224
225   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
226     syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
227
228   return (sock);
229 }
230
231 int getsocket6(struct sockaddr_in6 *sin, int bufspace, char *int_name)
232 {
233   int sock, on = 1;
234
235   if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 
236     {
237       perror("socket");
238       syslog(LOG_ERR, "socket: %m");
239       return (-1);
240     }
241
242   for (on = bufspace; ; on -= 1024) 
243     {
244       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
245                      &on, sizeof (on)) == 0)
246         break;
247       if (on <= 8*1024) 
248         {
249           perror("setsockopt");
250           syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
251           break;
252         }
253     }
254
255   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
256     {
257       perror("SO_REUSEADDR failed");
258       return (-1);
259     }
260
261   if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) 
262     {
263       perror("bind");
264       syslog(LOG_ERR, "bind: %m");
265       close(sock);
266       return (-1);
267     }
268
269   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
270     syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
271
272   return (sock);
273 }
274
275 int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
276 {
277   return 0;
278 }