Include net_os.h to fix prototype warnings.
[olsrd.git] / src / bsd / net.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: net.c,v 1.5 2004/11/17 17:14:43 tlopatic Exp $
23  *
24  */
25
26 #include "../defs.h"
27 #include "../net_os.h"
28 #include "net.h"
29
30 #include <sys/sysctl.h>
31
32 static int ignore_redir;
33 static int send_redir;
34 static int gateway;
35
36 static int first_time = 1;
37
38 static int set_sysctl_int(char *name, int new)
39 {
40   int old;
41   unsigned int len = sizeof (old);
42
43   if (sysctlbyname(name, &old, &len, &new, sizeof (new)) < 0)
44     return -1;
45
46   return old;
47 }
48
49 int enable_ip_forwarding(int version)
50 {
51   char *name;
52
53   if (olsr_cnf->ip_version == AF_INET)
54     name = "net.inet.ip.forwarding";
55
56   else
57     name = "net.inet6.ip6.forwarding";
58
59   gateway = set_sysctl_int(name, 1);
60
61   if (gateway < 0)
62     {
63       fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually. Continuing in 3 seconds...\n");
64       sleep(3);
65     }
66
67   return 1;
68 }
69
70 int disable_redirects(char *if_name, int index, int version)
71 {
72   char *name;
73
74   // this function gets called for each interface olsrd uses; however,
75   // FreeBSD can only globally control ICMP redirects, and not on a
76   // per-interface basis; hence, only disable ICMP redirects on the first
77   // invocation
78
79   if (first_time == 0)
80     return 1;
81
82   first_time = 0;
83
84   // do not accept ICMP redirects
85
86   if (olsr_cnf->ip_version == AF_INET)
87     name = "net.inet.icmp.drop_redirect";
88
89   else
90     name = "net.inet6.icmp6.drop_redirect";
91
92   ignore_redir = set_sysctl_int(name, 1);
93
94   if (ignore_redir < 0)
95     {
96       fprintf(stderr, "Cannot disable incoming ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
97       sleep(3);
98     }
99
100   // do not send ICMP redirects
101
102   if (olsr_cnf->ip_version == AF_INET)
103     name = "net.inet.ip.redirect";
104
105   else
106     name = "net.inet6.ip6.redirect";
107
108   send_redir = set_sysctl_int(name, 0);
109
110   if (send_redir < 0)
111     {
112       fprintf(stderr, "Cannot disable outgoing ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
113       sleep(3);
114     }
115
116   return 1;
117 }
118
119 int deactivate_spoof(char *if_name, int index, int version)
120 {
121   return 1;
122 }
123
124 int restore_settings(int version)
125 {
126   char *name;
127
128   // reset IP forwarding
129
130   if (olsr_cnf->ip_version == AF_INET)
131     name = "net.inet.ip.forwarding";
132
133   else
134     name = "net.inet6.ip6.forwarding";
135
136   set_sysctl_int(name, gateway);
137
138   // reset incoming ICMP redirects
139
140   if (olsr_cnf->ip_version == AF_INET)
141     name = "net.inet.icmp.drop_redirect";
142
143   else
144     name = "net.inet6.icmp6.drop_redirect";
145
146   set_sysctl_int(name, ignore_redir);
147
148   // reset outgoing ICMP redirects
149
150   if (olsr_cnf->ip_version == AF_INET)
151     name = "net.inet.ip.redirect";
152
153   else
154     name = "net.inet6.ip6.redirect";
155
156   set_sysctl_int(name, send_redir);
157
158   return 1;
159 }
160
161 int
162 getsocket(struct sockaddr *sa, int bufspace, char *int_name)
163 {
164   struct sockaddr_in *sin = (struct sockaddr_in *)sa;
165   int sock, on = 1;
166
167   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
168     {
169       perror("socket");
170       syslog(LOG_ERR, "socket: %m");
171       return (-1);
172     }
173
174   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
175     {
176       perror("setsockopt");
177       syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
178       close(sock);
179       return (-1);
180     }
181
182   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
183     {
184       perror("SO_REUSEADDR failed");
185       return (-1);
186     }
187
188   for (on = bufspace; ; on -= 1024) 
189     {
190       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
191                      &on, sizeof (on)) == 0)
192         break;
193       if (on <= 8*1024) 
194         {
195           perror("setsockopt");
196           syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
197           break;
198         }
199     }
200
201   if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) 
202     {
203       perror("bind");
204       syslog(LOG_ERR, "bind: %m");
205       close(sock);
206       return (-1);
207     }
208
209   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
210     syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
211
212   return (sock);
213 }
214
215 int getsocket6(struct sockaddr_in6 *sin, int bufspace, char *int_name)
216 {
217   int sock, on = 1;
218
219   if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 
220     {
221       perror("socket");
222       syslog(LOG_ERR, "socket: %m");
223       return (-1);
224     }
225
226   for (on = bufspace; ; on -= 1024) 
227     {
228       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
229                      &on, sizeof (on)) == 0)
230         break;
231       if (on <= 8*1024) 
232         {
233           perror("setsockopt");
234           syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
235           break;
236         }
237     }
238
239   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
240     {
241       perror("SO_REUSEADDR failed");
242       return (-1);
243     }
244
245   if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) 
246     {
247       perror("bind");
248       syslog(LOG_ERR, "bind: %m");
249       close(sock);
250       return (-1);
251     }
252
253   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
254     syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
255
256   return (sock);
257 }
258
259 int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
260 {
261   return 0;
262 }