2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 * Visit http://www.olsr.org for more information.
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.
39 * $Id: net.c,v 1.17 2005/03/02 08:58:12 kattemat Exp $
44 #include "parser.h" /* dnc: needed for call to packet_parser() */
48 #include <sys/param.h>
52 #include <net/if_var.h>
53 #include <net/ethernet.h>
55 #include <net80211/ieee80211.h>
56 #include <net80211/ieee80211_ioctl.h>
57 #include <dev/wi/if_wavelan_ieee.h>
58 #include <dev/wi/if_wireg.h>
60 //#define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */
61 //#define SIOCGWAVELAN SIOCGIFGENERIC
63 #include <sys/sysctl.h>
65 static int ignore_redir;
66 static int send_redir;
69 static int first_time = 1;
71 static int set_sysctl_int(char *name, int new)
74 unsigned int len = sizeof (old);
76 if (sysctlbyname(name, &old, &len, &new, sizeof (new)) < 0)
82 int enable_ip_forwarding(int version)
86 if (olsr_cnf->ip_version == AF_INET)
87 name = "net.inet.ip.forwarding";
90 name = "net.inet6.ip6.forwarding";
92 gateway = set_sysctl_int(name, 1);
96 fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually. Continuing in 3 seconds...\n");
103 int disable_redirects(char *if_name, int index, int version)
107 // this function gets called for each interface olsrd uses; however,
108 // FreeBSD can only globally control ICMP redirects, and not on a
109 // per-interface basis; hence, only disable ICMP redirects on the first
117 // do not accept ICMP redirects
119 if (olsr_cnf->ip_version == AF_INET)
120 name = "net.inet.icmp.drop_redirect";
123 name = "net.inet6.icmp6.drop_redirect";
125 ignore_redir = set_sysctl_int(name, 1);
127 if (ignore_redir < 0)
129 fprintf(stderr, "Cannot disable incoming ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
133 // do not send ICMP redirects
135 if (olsr_cnf->ip_version == AF_INET)
136 name = "net.inet.ip.redirect";
139 name = "net.inet6.ip6.redirect";
141 send_redir = set_sysctl_int(name, 0);
145 fprintf(stderr, "Cannot disable outgoing ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
152 int deactivate_spoof(char *if_name, int index, int version)
157 int restore_settings(int version)
161 // reset IP forwarding
163 if (olsr_cnf->ip_version == AF_INET)
164 name = "net.inet.ip.forwarding";
167 name = "net.inet6.ip6.forwarding";
169 set_sysctl_int(name, gateway);
171 // reset incoming ICMP redirects
173 if (olsr_cnf->ip_version == AF_INET)
174 name = "net.inet.icmp.drop_redirect";
177 name = "net.inet6.icmp6.drop_redirect";
179 set_sysctl_int(name, ignore_redir);
181 // reset outgoing ICMP redirects
183 if (olsr_cnf->ip_version == AF_INET)
184 name = "net.inet.ip.redirect";
187 name = "net.inet6.ip6.redirect";
189 set_sysctl_int(name, send_redir);
195 getsocket(struct sockaddr *sa, int bufspace, char *int_name)
197 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
200 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
203 syslog(LOG_ERR, "socket: %m");
207 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
209 perror("setsockopt");
210 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
215 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
217 perror("SO_REUSEADDR failed");
221 for (on = bufspace; ; on -= 1024)
223 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
224 &on, sizeof (on)) == 0)
228 perror("setsockopt");
229 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
234 if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0)
237 syslog(LOG_ERR, "bind: %m");
242 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
243 syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
248 int getsocket6(struct sockaddr_in6 *sin, int bufspace, char *int_name)
252 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
255 syslog(LOG_ERR, "socket: %m");
259 for (on = bufspace; ; on -= 1024)
261 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
262 &on, sizeof (on)) == 0)
266 perror("setsockopt");
267 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
272 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
274 perror("SO_REUSEADDR failed");
278 if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0)
281 syslog(LOG_ERR, "bind: %m");
286 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
287 syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
292 int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
301 * Wrapper for sendto(2)
309 const struct sockaddr *to,
312 return sendto(s, buf, len, flags, to, tolen);
317 * Wrapper for recvfrom(2)
325 struct sockaddr *from,
337 * Wrapper for select(2)
341 olsr_select(int nfds,
345 struct timeval *timeout)
356 check_wireless_interface(char *ifname)
362 memset((char *)&wreq, 0, sizeof(wreq));
363 memset((char *)&ifr, 0, sizeof(ifr));
365 wreq.wi_len = WI_MAX_DATALEN;
366 wreq.wi_type = WI_RID_IFACE_STATS;
368 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
369 ifr.ifr_data = (caddr_t)&wreq;
371 return (ioctl(ioctl_s, SIOCGWAVELAN, &ifr) >= 0) ? 1 : 0;
377 #include <sys/sockio.h>
380 calculate_if_metric(char *ifname)
382 if(check_wireless_interface(ifname))
391 /* Andreas: Perhaps SIOCGIFMEDIA is the way to do this? */
392 struct ifmediareq ifm;
394 memset(&ifm, 0, sizeof(ifm));
395 strlcpy(ifm.ifm_name, ifname, sizeof(ifm.ifm_name));
397 if(ioctl(ioctl_s, SIOCGIFMEDIA, &ifm) < 0)
399 OLSR_PRINTF(1, "Error SIOCGIFMEDIA(%s)\n", ifm.ifm_name)
400 return WEIGHT_ETHERNET_DEFAULT;
403 OLSR_PRINTF(1, "%s: STATUS 0x%08x\n", ifm.ifm_name, ifm.ifm_status)
405 return WEIGHT_ETHERNET_DEFAULT;