3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
42 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
43 #define ifr_netmask ifr_addr
48 #include "interfaces.h"
53 #include "socket_parser.h"
55 #include "scheduler.h"
56 #include "generate_msg.h"
58 #include "lq_packet.h"
62 #include <sys/types.h>
64 #include <net/if_arp.h>
65 #include <netinet/in_systm.h>
66 #include <netinet/ip.h>
67 #include <arpa/inet.h>
71 #define BUFSPACE (127*1024) /* max. input buffer size to request */
74 set_flag(char *ifname, short flag __attribute__ ((unused)))
78 strscpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
81 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
82 fprintf(stderr, "ioctl (get interface flags)");
86 strscpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
88 //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
90 if (!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING))) {
92 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
94 if (ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0) {
95 fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
104 check_interface_updates(void *foo __attribute__ ((unused)))
106 struct olsr_if *tmp_if;
109 OLSR_PRINTF(3, "Checking for updates in the interface set\n");
112 for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
113 if (tmp_if->host_emul)
116 if (olsr_cnf->host_emul) /* XXX: TEMPORARY! */
119 if (!tmp_if->cnf->autodetect_chg) {
121 /* Don't check this interface */
122 OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name);
127 if (tmp_if->configured) {
128 chk_if_changed(tmp_if);
130 chk_if_up(tmp_if, 3);
138 * Checks if an initialized interface is changed
139 * that is if it has been set down or the address
142 *@param iface the olsr_if struct describing the interface
145 chk_if_changed(struct olsr_if *iface)
147 struct interface *ifp;
149 struct sockaddr_in6 tmp_saddr6;
154 OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
157 if (iface->host_emul)
163 /* Should not happen */
164 iface->configured = 0;
168 memset(&ifr, 0, sizeof(struct ifreq));
169 strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
171 /* Get flags (and check if interface exists) */
172 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
173 OLSR_PRINTF(3, "No such interface: %s\n", iface->name);
174 goto remove_interface;
177 ifp->int_flags = ifr.ifr_flags;
180 * First check if the interface is set DOWN
183 if ((ifp->int_flags & IFF_UP) == 0) {
184 OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name);
185 goto remove_interface;
189 * We do all the interface type checks over.
190 * This is because the interface might be a PCMCIA card. Therefore
191 * It might not be the same physical interface as we configured earlier.
194 /* Check broadcast */
195 if ((olsr_cnf->ip_version == AF_INET) && !iface->cnf->ipv4_multicast.v4.s_addr && /* Skip if fixed bcast */
196 (!(ifp->int_flags & IFF_BROADCAST))) {
197 OLSR_PRINTF(3, "\tNo broadcast - removing\n");
198 goto remove_interface;
201 if (ifp->int_flags & IFF_LOOPBACK) {
202 OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n");
203 goto remove_interface;
206 ifp->is_hcif = false;
208 /* trying to detect if interface is wireless. */
209 ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
211 /* Set interface metric */
212 if (iface->cnf->weight.fixed)
213 ifp->int_metric = iface->cnf->weight.value;
215 ifp->int_metric = calculate_if_metric(ifr.ifr_name);
218 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
221 ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
223 if (ifp->int_mtu != ifr.ifr_mtu) {
224 ifp->int_mtu = ifr.ifr_mtu;
225 /* Create new outputbuffer */
226 net_remove_buffer(ifp); /* Remove old */
231 /* Get interface index */
232 ifp->if_index = if_nametoindex(ifr.ifr_name);
235 * Now check if the IP has changed
239 if (olsr_cnf->ip_version == AF_INET6) {
240 struct ipaddr_str buf;
241 /* Get dst interface address */
243 if (0 == get_ipv6_address(iface->name, &tmp_saddr6, (iface->cnf->ipv6_src.prefix_len == 0) ? NULL : (&iface->cnf->ipv6_src))) {
244 OLSR_PRINTF(3, "\tCould not find ip address for %s with prefix %s.\n", ifr.ifr_name, olsr_ip_prefix_to_string(&iface->cnf->ipv6_src));
245 goto remove_interface;
249 OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&buf, &iface->cnf->ipv6_multicast.v6));
252 if (memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0) {
253 OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name);
254 OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&buf, &ifp->int6_addr.sin6_addr));
255 OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
257 /* deactivated to prevent change of originator IP */
259 /* Check main addr */
260 if (memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0) {
261 /* Update main addr */
262 memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
266 memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
267 memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
269 olsr_trigger_ifchange(ifp, IFCHG_IF_UPDATE);
278 struct ipaddr_str buf;
279 /* Check interface address (IPv4) */
280 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
281 OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n");
282 goto remove_interface;
285 OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
289 (&((struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifp->int_addr)->sin_addr.s_addr, &((struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_addr)->sin_addr.s_addr,
290 olsr_cnf->ipsize) != 0) {
292 OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name);
293 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_addr.sin_addr));
294 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
296 ifp->int_addr = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_addr;
297 /* deactivated to prevent change of originator IP */
299 if (memcmp(&olsr_cnf->main_addr, &ifp->ip_addr, olsr_cnf->ipsize) == 0) {
300 OLSR_PRINTF(1, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
301 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
302 memcpy(&olsr_cnf->main_addr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, olsr_cnf->ipsize);
305 memcpy(&ifp->ip_addr, &((struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_addr)->sin_addr.s_addr, olsr_cnf->ipsize);
311 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
312 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
313 goto remove_interface;
316 OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
320 (&((struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifp->int_netmask)->sin_addr.s_addr, &((struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_netmask)->sin_addr.s_addr,
321 olsr_cnf->ipsize) != 0) {
323 OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
324 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_netmask.sin_addr));
325 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
327 ifp->int_netmask = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_netmask;
332 if (!iface->cnf->ipv4_multicast.v4.s_addr) {
333 /* Check broadcast address */
334 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) {
335 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
336 goto remove_interface;
339 OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
342 if (ifp->int_broadaddr.sin_addr.s_addr != ((struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_broadaddr)->sin_addr.s_addr) {
344 OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
345 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_broadaddr.sin_addr));
346 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
348 ifp->int_broadaddr = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_broadaddr;
355 olsr_trigger_ifchange(ifp, IFCHG_IF_UPDATE);
361 olsr_remove_interface(iface, false);
367 * Initializes the special interface used in
368 * host-client emulation
371 add_hemu_if(struct olsr_if *iface)
373 struct interface *ifp;
374 union olsr_ip_addr null_addr;
376 struct ipaddr_str buf;
379 if (!iface->host_emul)
382 ifp = olsr_malloc(sizeof(struct interface), "Interface update 2");
384 memset(ifp, 0, sizeof(struct interface));
386 iface->configured = true;
389 name_size = strlen("hcif01") + 1;
391 ifp->int_name = olsr_malloc(name_size, "Interface update 3");
394 strscpy(ifp->int_name, "hcif01", name_size);
396 OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
398 OLSR_PRINTF(1, " Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
400 OLSR_PRINTF(1, " NB! This is a emulated interface\n that does not exist in the kernel!\n");
402 ifp->int_next = ifnet;
405 memset(&null_addr, 0, olsr_cnf->ipsize);
406 if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
407 olsr_cnf->main_addr = iface->hemu_ip;
408 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
409 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
412 ifp->int_mtu = OLSR_DEFAULT_MTU;
414 ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
419 if (olsr_cnf->ip_version == AF_INET) {
420 struct sockaddr_in sin;
422 memset(&sin, 0, sizeof(sin));
424 sin.sin_family = AF_INET;
425 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
426 sin.sin_port = htons(10150);
429 ifp->ip_addr.v4 = iface->hemu_ip.v4;
431 memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
434 *We create one socket for each interface and bind
435 *the socket to it. This to ensure that we can control
436 *on what interface the message is transmitted
439 ifp->olsr_socket = gethemusocket(&sin);
441 if (ifp->olsr_socket < 0) {
442 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
443 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
444 olsr_cnf->exit_value = EXIT_FAILURE;
445 kill(getpid(), SIGINT);
450 memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
454 *We create one socket for each interface and bind
455 *the socket to it. This to ensure that we can control
456 *on what interface the message is transmitted
459 ifp->olsr_socket = gethcsocket6(&addrsock6, BUFSPACE, ifp->int_name);
461 join_mcast(ifp, ifp->olsr_socket);
463 if (ifp->olsr_socket < 0) {
464 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
465 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
466 olsr_cnf->exit_value = EXIT_FAILURE;
467 kill(getpid(), SIGINT);
472 /* Send IP as first 4/16 bytes on socket */
473 memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
474 addr[0] = htonl(addr[0]);
475 addr[1] = htonl(addr[1]);
476 addr[2] = htonl(addr[2]);
477 addr[3] = htonl(addr[3]);
479 if (send(ifp->olsr_socket, addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize) {
480 fprintf(stderr, "Error sending IP!");
483 /* Register socket */
484 add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
487 * Register functions for periodic message generation
490 ifp->hello_gen_timer =
491 olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
492 olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie->ci_id);
494 olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
495 olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie->ci_id);
497 olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
498 mid_gen_timer_cookie->ci_id);
500 olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
501 hna_gen_timer_cookie->ci_id);
503 /* Recalculate max topology hold time */
504 if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
505 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
507 ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
508 ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
509 ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
510 ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
511 ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
513 ifp->mode = iface->cnf->mode;
518 static char basenamestr[32];
519 static const char *if_basename(const char *name);
521 if_basename(const char *name)
523 char *p = strchr(name, ':');
524 if (NULL == p || p - name >= (int)(sizeof(basenamestr) / sizeof(basenamestr[0]) - 1)) {
527 memcpy(basenamestr, name, p - name);
528 basenamestr[p - name] = 0;
533 * Initializes a interface described by iface,
534 * if it is set up and is of the correct type.
536 *@param iface the olsr_if struct describing the interface
537 *@param so the socket to use for ioctls
541 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
543 struct interface ifs, *ifp;
545 union olsr_ip_addr null_addr;
548 int precedence = IPTOS_PREC(olsr_cnf->tos);
549 int tos_bits = IPTOS_TOS(olsr_cnf->tos);
552 if (iface->host_emul)
555 memset(&ifr, 0, sizeof(struct ifreq));
556 memset(&ifs, 0, sizeof(struct interface));
557 strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
559 OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
561 /* Get flags (and check if interface exists) */
562 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
563 OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
567 ifs.int_flags = ifr.ifr_flags;
569 if ((ifs.int_flags & IFF_UP) == 0) {
570 OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n");
574 /* Check broadcast */
575 if ((olsr_cnf->ip_version == AF_INET) && !iface->cnf->ipv4_multicast.v4.s_addr && /* Skip if fixed bcast */
576 (!(ifs.int_flags & IFF_BROADCAST))) {
577 OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
581 if (ifs.int_flags & IFF_LOOPBACK) {
582 OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
588 /* trying to detect if interface is wireless. */
589 ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
592 OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
594 OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
597 if (olsr_cnf->ip_version == AF_INET6) {
598 /* Get interface address */
599 struct ipaddr_str buf;
601 if (0 == get_ipv6_address(iface->name, &ifs.int6_addr, (iface->cnf->ipv6_src.prefix_len == 0) ? NULL : (&iface->cnf->ipv6_src))) {
602 OLSR_PRINTF(3, "\tCould not find ip address for %s with prefix %s.\n", ifr.ifr_name, olsr_ip_prefix_to_string(&iface->cnf->ipv6_src));
605 OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&buf, &iface->cnf->ipv6_multicast.v6));
608 memset(&ifs.int6_multaddr, 0, sizeof(ifs.int6_multaddr));
609 ifs.int6_multaddr.sin6_family = AF_INET6;
610 ifs.int6_multaddr.sin6_flowinfo = htonl(0);
611 ifs.int6_multaddr.sin6_scope_id = if_nametoindex(ifr.ifr_name);
612 ifs.int6_multaddr.sin6_port = htons(olsr_cnf->olsrport);
613 ifs.int6_multaddr.sin6_addr = iface->cnf->ipv6_multicast.v6;
616 ifs.int6_multaddr.sin6_scope_id = 0;
619 OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
624 /* Get interface address (IPv4) */
625 if (iface->cnf->ipv4_src.v4.s_addr) {
626 ifs.int_addr.sin_addr = iface->cnf->ipv4_src.v4;
629 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
630 OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
634 ifs.int_addr = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_addr;
637 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
638 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
642 ifs.int_netmask = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_netmask;
644 /* Find broadcast address */
645 if (iface->cnf->ipv4_multicast.v4.s_addr) {
646 /* Specified broadcast */
647 memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, &iface->cnf->ipv4_multicast.v4, sizeof(uint32_t));
650 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) {
651 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
655 ifs.int_broadaddr = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN)&ifr.ifr_broadaddr;
658 /* Deactivate IP spoof filter */
659 deactivate_spoof(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
661 /* Disable ICMP redirects */
662 disable_redirects(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
666 /* Get interface index */
668 ifs.if_index = if_nametoindex(ifr.ifr_name);
670 /* Set interface metric */
671 if (iface->cnf->weight.fixed)
672 ifs.int_metric = iface->cnf->weight.value;
674 ifs.int_metric = calculate_if_metric(ifr.ifr_name);
675 OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
678 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
679 ifs.int_mtu = OLSR_DEFAULT_MTU;
681 ifs.int_mtu = ifr.ifr_mtu;
683 ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
685 ifs.ttl_index = -32; /* For the first 32 TC's, fish-eye is disabled */
688 net_add_buffer(&ifs);
690 OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
692 olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
693 OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_index);
695 if (olsr_cnf->ip_version == AF_INET) {
696 struct ipaddr_str buf;
697 OLSR_PRINTF(1, "\tAddress:%s\n", ip4_to_string(&buf, ifs.int_addr.sin_addr));
698 OLSR_PRINTF(1, "\tNetmask:%s\n", ip4_to_string(&buf, ifs.int_netmask.sin_addr));
699 OLSR_PRINTF(1, "\tBroadcast address:%s\n", ip4_to_string(&buf, ifs.int_broadaddr.sin_addr));
701 struct ipaddr_str buf;
702 OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
703 OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
706 ifp = olsr_malloc(sizeof(struct interface), "Interface update 2");
708 iface->configured = 1;
712 memcpy(ifp, &ifs, sizeof(struct interface));
714 ifp->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
715 if (olsr_cnf->max_jitter == 0) {
716 /* max_jitter determines the max time to store to-be-send-messages, correlated with random() */
717 olsr_cnf->max_jitter =
718 ifp->immediate_send_tc ? iface->cnf->tc_params.emission_interval : iface->cnf->hello_params.emission_interval;
721 name_size = strlen(if_basename(ifr.ifr_name)) + 1;
722 ifp->gen_properties = NULL;
723 ifp->int_name = olsr_malloc(name_size, "Interface update 3");
724 strscpy(ifp->int_name, if_basename(ifr.ifr_name), name_size);
725 ifp->int_next = ifnet;
728 if (olsr_cnf->ip_version == AF_INET) {
730 ifp->ip_addr.v4 = ifp->int_addr.sin_addr;
732 *We create one socket for each interface and bind
733 *the socket to it. This to ensure that we can control
734 *on what interface the message is transmitted
737 ifp->olsr_socket = getsocket(BUFSPACE, ifp);
738 ifp->send_socket = getsocket(0, ifp);
740 if (ifp->olsr_socket < 0) {
741 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
742 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
743 olsr_cnf->exit_value = EXIT_FAILURE;
744 kill(getpid(), SIGINT);
749 ifp->ip_addr.v6 = ifp->int6_addr.sin6_addr;
752 *We create one socket for each interface and bind
753 *the socket to it. This to ensure that we can control
754 *on what interface the message is transmitted
757 ifp->olsr_socket = getsocket6(BUFSPACE, ifp);
758 ifp->send_socket = getsocket6(0, ifp);
760 join_mcast(ifp, ifp->olsr_socket);
762 if (ifp->olsr_socket < 0) {
763 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
764 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
765 olsr_cnf->exit_value = EXIT_FAILURE;
766 kill(getpid(), SIGINT);
771 set_buffer_timer(ifp);
773 /* Register socket */
774 add_olsr_socket(ifp->olsr_socket, &olsr_input);
775 if (ifp->olsr_socket != ifp->send_socket) {
776 add_olsr_socket(ifp->send_socket, &olsr_input);
782 if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char *)&precedence, sizeof(precedence)) < 0) {
783 perror("setsockopt(SO_PRIORITY)");
784 olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
786 if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char *)&tos_bits, sizeof(tos_bits)) < 0) {
787 perror("setsockopt(IP_TOS)");
788 olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
793 *Initialize sequencenumber as a random 16bit value
795 ifp->olsr_seqnum = random() & 0xFFFF;
798 * Set main address if this is the only interface
800 memset(&null_addr, 0, olsr_cnf->ipsize);
801 if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
802 struct ipaddr_str buf;
803 olsr_cnf->main_addr = ifp->ip_addr;
804 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
805 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
809 * Register functions for periodic message generation
811 ifp->hello_gen_timer =
812 olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
813 olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie->ci_id);
815 olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
816 olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie->ci_id);
818 olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
819 mid_gen_timer_cookie->ci_id);
821 olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
822 hna_gen_timer_cookie->ci_id);
824 /* Recalculate max topology hold time */
825 if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval) {
826 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
828 ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
829 ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
830 ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
831 ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
832 ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
834 ifp->mode = iface->cnf->mode;
837 *Call possible ifchange functions registered by plugins
839 olsr_trigger_ifchange(ifp, IFCHG_IF_ADD);
847 * indent-tabs-mode: nil