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: ifnet.c,v 1.56 2007/12/02 19:00:28 bernd67 Exp $
43 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
44 #define ifr_netmask ifr_addr
49 #include "interfaces.h"
54 #include "socket_parser.h"
56 #include "scheduler.h"
57 #include "generate_msg.h"
59 #include "lq_packet.h"
63 #include <sys/types.h>
65 #include <net/if_arp.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
68 #include <arpa/inet.h>
72 int bufspace = 127*1024; /* max. input buffer size to request */
76 set_flag(char *ifname, short flag __attribute__((unused)))
80 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
83 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
85 fprintf(stderr,"ioctl (get interface flags)");
89 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
91 //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
93 if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)))
96 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
98 if(ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
100 fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
112 check_interface_updates(void *foo __attribute__((unused)))
114 struct olsr_if *tmp_if;
117 OLSR_PRINTF(3, "Checking for updates in the interface set\n");
120 for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
122 if(tmp_if->host_emul)
125 if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
128 if(!tmp_if->cnf->autodetect_chg)
131 /* Don't check this interface */
132 OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name);
137 if(tmp_if->configured)
139 chk_if_changed(tmp_if);
143 chk_if_up(tmp_if, 3);
151 * Checks if an initialized interface is changed
152 * that is if it has been set down or the address
155 *@param iface the olsr_if struct describing the interface
158 chk_if_changed(struct olsr_if *iface)
160 struct interface *ifp, *tmp_ifp;
162 struct sockaddr_in6 tmp_saddr6;
167 OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
177 /* Should not happen */
178 iface->configured = 0;
182 memset(&ifr, 0, sizeof(struct ifreq));
183 strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
186 /* Get flags (and check if interface exists) */
187 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
189 OLSR_PRINTF(3, "No such interface: %s\n", iface->name);
190 goto remove_interface;
193 ifp->int_flags = ifr.ifr_flags;
196 * First check if the interface is set DOWN
199 if ((ifp->int_flags & IFF_UP) == 0)
201 OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name);
202 goto remove_interface;
206 * We do all the interface type checks over.
207 * This is because the interface might be a PCMCIA card. Therefore
208 * It might not be the same physical interface as we configured earlier.
211 /* Check broadcast */
212 if ((olsr_cnf->ip_version == AF_INET) &&
213 !iface->cnf->ipv4_broadcast.v4.s_addr && /* Skip if fixed bcast */
214 (!(ifp->int_flags & IFF_BROADCAST)))
216 OLSR_PRINTF(3, "\tNo broadcast - removing\n");
217 goto remove_interface;
220 if (ifp->int_flags & IFF_LOOPBACK)
222 OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n");
223 goto remove_interface;
226 ifp->is_hcif = OLSR_FALSE;
228 /* trying to detect if interface is wireless. */
229 ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
231 /* Set interface metric */
232 if(iface->cnf->weight.fixed)
233 ifp->int_metric = iface->cnf->weight.value;
235 ifp->int_metric = calculate_if_metric(ifr.ifr_name);
238 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
242 ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
244 if(ifp->int_mtu != ifr.ifr_mtu)
246 ifp->int_mtu = ifr.ifr_mtu;
247 /* Create new outputbuffer */
248 net_remove_buffer(ifp); /* Remove old */
254 /* Get interface index */
255 ifp->if_index = if_nametoindex(ifr.ifr_name);
258 * Now check if the IP has changed
262 if(olsr_cnf->ip_version == AF_INET6)
264 #if !defined(NODEBUG) && defined(DEBUG)
265 struct ipaddr_str buf;
267 /* Get interface address */
269 if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0)
271 if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
272 OLSR_PRINTF(3, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
274 OLSR_PRINTF(3, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
277 goto remove_interface;
281 OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
284 if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0)
287 struct ipaddr_str buf;
289 OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name);
290 OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&buf, &ifp->int6_addr.sin6_addr));
291 OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
293 /* Check main addr */
294 if(memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0)
296 /* Update main addr */
297 memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
301 memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
302 memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
304 run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
314 struct ipaddr_str buf;
315 /* Check interface address (IPv4)*/
316 if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0)
318 OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n");
319 goto remove_interface;
323 OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
326 if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
327 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
328 olsr_cnf->ipsize) != 0)
331 OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name);
332 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_addr.sin_addr));
333 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
335 ifp->int_addr = *(struct sockaddr_in *)&ifr.ifr_addr;
337 if(memcmp(&olsr_cnf->main_addr,
339 olsr_cnf->ipsize) == 0)
341 OLSR_PRINTF(1, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
342 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
343 memcpy(&olsr_cnf->main_addr,
344 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
348 memcpy(&ifp->ip_addr,
349 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
356 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0)
358 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
359 goto remove_interface;
363 OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
366 if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
367 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr,
368 olsr_cnf->ipsize) != 0)
371 struct ipaddr_str buf;
374 OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
375 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_netmask.sin_addr));
376 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
378 ifp->int_netmask = *(struct sockaddr_in *)&ifr.ifr_netmask;
383 if(!iface->cnf->ipv4_broadcast.v4.s_addr)
385 /* Check broadcast address */
386 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0)
388 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
389 goto remove_interface;
393 OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
396 if(ifp->int_broadaddr.sin_addr.s_addr != ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr)
399 struct ipaddr_str buf;
402 OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
403 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_broadaddr.sin_addr));
404 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
406 ifp->int_broadaddr = *(struct sockaddr_in *)&ifr.ifr_broadaddr;
413 run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
419 OLSR_PRINTF(1, "Removing interface %s\n", iface->name);
420 olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
422 del_if_link_entries(&ifp->ip_addr);
425 *Call possible ifchange functions registered by plugins
427 run_ifchg_cbs(ifp, IFCHG_IF_REMOVE);
432 ifnet = ifp->int_next;
437 while(tmp_ifp->int_next != ifp)
439 tmp_ifp = tmp_ifp->int_next;
441 tmp_ifp->int_next = ifp->int_next;
445 /* Remove output buffer */
446 net_remove_buffer(ifp);
448 /* Check main addr */
449 if(ipequal(&olsr_cnf->main_addr, &ifp->ip_addr))
453 /* No more interfaces */
454 memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
455 OLSR_PRINTF(1, "No more interfaces...\n");
459 struct ipaddr_str buf;
460 olsr_cnf->main_addr = ifnet->ip_addr;
461 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
462 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
468 * Deregister scheduled functions
471 if (olsr_cnf->lq_level == 0)
473 olsr_remove_scheduler_event(&generate_hello,
475 iface->cnf->hello_params.emission_interval,
478 olsr_remove_scheduler_event(&generate_tc,
480 iface->cnf->tc_params.emission_interval,
487 olsr_remove_scheduler_event(&olsr_output_lq_hello,
489 iface->cnf->hello_params.emission_interval,
492 olsr_remove_scheduler_event(&olsr_output_lq_tc,
494 iface->cnf->tc_params.emission_interval,
499 olsr_remove_scheduler_event(&generate_mid,
501 iface->cnf->mid_params.emission_interval,
504 olsr_remove_scheduler_event(&generate_hna,
506 iface->cnf->hna_params.emission_interval,
512 iface->configured = 0;
513 iface->interf = NULL;
514 /* Close olsr socket */
515 close(ifp->olsr_socket);
516 remove_olsr_socket(ifp->olsr_socket, &olsr_input);
522 if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
524 OLSR_PRINTF(1, "No more active interfaces - exiting.\n");
525 olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
526 olsr_cnf->exit_value = EXIT_FAILURE;
527 kill(getpid(), SIGINT);
535 * Initializes the special interface used in
536 * host-client emulation
539 add_hemu_if(struct olsr_if *iface)
541 struct interface *ifp;
542 union olsr_ip_addr null_addr;
544 struct ipaddr_str buf;
546 if(!iface->host_emul)
549 ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
551 memset(ifp, 0, sizeof (struct interface));
553 iface->configured = OLSR_TRUE;
556 ifp->is_hcif = OLSR_TRUE;
557 ifp->int_name = olsr_malloc(strlen("hcif01") + 1, "Interface update 3");
560 strcpy(ifp->int_name, "hcif01");
562 OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
564 OLSR_PRINTF(1, " Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
566 OLSR_PRINTF(1, " NB! This is a emulated interface\n that does not exist in the kernel!\n");
568 ifp->int_next = ifnet;
571 memset(&null_addr, 0, olsr_cnf->ipsize);
572 if(ipequal(&null_addr, &olsr_cnf->main_addr))
574 olsr_cnf->main_addr = iface->hemu_ip;
575 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
576 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
579 ifp->int_mtu = OLSR_DEFAULT_MTU;
581 ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
587 if(olsr_cnf->ip_version == AF_INET)
589 struct sockaddr_in sin;
591 memset(&sin, 0, sizeof(sin));
593 sin.sin_family = AF_INET;
594 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
595 sin.sin_port = htons(10150);
598 ifp->ip_addr.v4 = iface->hemu_ip.v4;
600 memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
603 *We create one socket for each interface and bind
604 *the socket to it. This to ensure that we can control
605 *on what interface the message is transmitted
608 ifp->olsr_socket = gethemusocket(&sin);
610 if (ifp->olsr_socket < 0)
612 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
613 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
614 olsr_cnf->exit_value = EXIT_FAILURE;
615 kill(getpid(), SIGINT);
622 memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
626 *We create one socket for each interface and bind
627 *the socket to it. This to ensure that we can control
628 *on what interface the message is transmitted
631 ifp->olsr_socket = gethcsocket6(&addrsock6, bufspace, ifp->int_name);
633 join_mcast(ifp, ifp->olsr_socket);
635 if (ifp->olsr_socket < 0)
637 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
638 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
639 olsr_cnf->exit_value = EXIT_FAILURE;
640 kill(getpid(), SIGINT);
646 /* Send IP as first 4/16 bytes on socket */
647 memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
648 addr[0] = htonl(addr[0]);
649 addr[1] = htonl(addr[1]);
650 addr[2] = htonl(addr[2]);
651 addr[3] = htonl(addr[3]);
653 if(send(ifp->olsr_socket, addr , olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
655 fprintf(stderr, "Error sending IP!");
658 /* Register socket */
659 add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
662 if (olsr_cnf->lq_level == 0)
664 olsr_register_scheduler_event(&generate_hello,
666 iface->cnf->hello_params.emission_interval,
669 olsr_register_scheduler_event(&generate_tc,
671 iface->cnf->tc_params.emission_interval,
678 olsr_register_scheduler_event(&olsr_output_lq_hello,
680 iface->cnf->hello_params.emission_interval,
683 olsr_register_scheduler_event(&olsr_output_lq_tc,
685 iface->cnf->tc_params.emission_interval,
690 olsr_register_scheduler_event(&generate_mid,
692 iface->cnf->mid_params.emission_interval,
695 olsr_register_scheduler_event(&generate_hna,
697 iface->cnf->hna_params.emission_interval,
701 /* Recalculate max jitter */
703 if((olsr_cnf->max_jitter == 0) ||
704 ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
705 olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
707 /* Recalculate max topology hold time */
708 if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
709 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
711 ifp->hello_etime = iface->cnf->hello_params.emission_interval;
712 ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
713 ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
714 ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
715 ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
720 static char basenamestr[32];
721 static const char* if_basename(const char* name);
722 static const char* if_basename(const char* name)
724 char *p = strchr(name, ':');
725 if (NULL == p || p - name >= (int)(sizeof(basenamestr) / sizeof(basenamestr[0]) - 1)) {
728 memcpy(basenamestr, name, p - name);
729 basenamestr[p - name] = 0;
734 * Initializes a interface described by iface,
735 * if it is set up and is of the correct type.
737 *@param iface the olsr_if struct describing the interface
738 *@param so the socket to use for ioctls
742 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__((unused)))
744 struct interface ifs, *ifp;
746 union olsr_ip_addr null_addr;
748 int precedence = IPTOS_PREC(olsr_cnf->tos);
749 int tos_bits = IPTOS_TOS(olsr_cnf->tos);
755 memset(&ifr, 0, sizeof(struct ifreq));
756 strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
758 OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
760 /* Get flags (and check if interface exists) */
761 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
763 OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
767 memset(&ifs.netbuf, 0, sizeof(struct olsr_netbuf));
768 ifs.int_flags = ifr.ifr_flags;
771 if ((ifs.int_flags & IFF_UP) == 0)
773 OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n");
777 /* Check broadcast */
778 if ((olsr_cnf->ip_version == AF_INET) &&
779 !iface->cnf->ipv4_broadcast.v4.s_addr && /* Skip if fixed bcast */
780 (!(ifs.int_flags & IFF_BROADCAST)))
782 OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
787 if (ifs.int_flags & IFF_LOOPBACK)
789 OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
793 ifs.is_hcif = OLSR_FALSE;
795 /* trying to detect if interface is wireless. */
796 ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
799 OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
801 OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
805 if(olsr_cnf->ip_version == AF_INET6)
807 /* Get interface address */
809 struct ipaddr_str buf;
811 if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
813 if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
814 OLSR_PRINTF(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
816 OLSR_PRINTF(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
821 OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
824 ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) ?
825 iface->cnf->ipv6_multi_site.v6 :
826 iface->cnf->ipv6_multi_glbl.v6;
827 /* Set address family */
828 ifs.int6_multaddr.sin6_family = AF_INET6;
830 ifs.int6_multaddr.sin6_port = htons(OLSRPORT);
833 ifs.int6_multaddr.sin6_scope_id = 0;
836 OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
842 /* Get interface address (IPv4)*/
843 if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0)
845 OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
849 ifs.int_addr = *(struct sockaddr_in *)&ifr.ifr_addr;
853 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0)
855 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
859 ifs.int_netmask = *(struct sockaddr_in *)&ifr.ifr_netmask;
861 /* Find broadcast address */
862 if(iface->cnf->ipv4_broadcast.v4.s_addr)
864 /* Specified broadcast */
865 memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
866 memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr,
867 &iface->cnf->ipv4_broadcast.v4,
873 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0)
875 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
879 ifs.int_broadaddr = *(struct sockaddr_in *)&ifr.ifr_broadaddr;
882 /* Deactivate IP spoof filter */
883 deactivate_spoof(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
885 /* Disable ICMP redirects */
886 disable_redirects(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
891 /* Get interface index */
893 ifs.if_index = if_nametoindex(ifr.ifr_name);
895 /* Set interface metric */
896 if(iface->cnf->weight.fixed)
897 ifs.int_metric = iface->cnf->weight.value;
899 ifs.int_metric = calculate_if_metric(ifr.ifr_name);
900 OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
903 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
904 ifs.int_mtu = OLSR_DEFAULT_MTU;
906 ifs.int_mtu = ifr.ifr_mtu;
908 ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
913 net_add_buffer(&ifs);
915 OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
917 olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
918 OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_index);
920 if(olsr_cnf->ip_version == AF_INET)
923 struct ipaddr_str buf;
925 OLSR_PRINTF(1, "\tAddress:%s\n", ip4_to_string(&buf, ifs.int_addr.sin_addr));
926 OLSR_PRINTF(1, "\tNetmask:%s\n", ip4_to_string(&buf, ifs.int_netmask.sin_addr));
927 OLSR_PRINTF(1, "\tBroadcast address:%s\n", ip4_to_string(&buf, ifs.int_broadaddr.sin_addr));
932 struct ipaddr_str buf;
934 OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
935 OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
938 ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
940 iface->configured = 1;
943 memcpy(ifp, &ifs, sizeof(struct interface));
945 ifp->gen_properties = NULL;
946 ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
948 strcpy(ifp->int_name, if_basename(ifr.ifr_name));
949 /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
950 ifp->int_next = ifnet;
953 if(olsr_cnf->ip_version == AF_INET)
956 ifp->ip_addr.v4 = ifp->int_addr.sin_addr;
958 *We create one socket for each interface and bind
959 *the socket to it. This to ensure that we can control
960 *on what interface the message is transmitted
963 ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
965 if (ifp->olsr_socket < 0)
967 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
968 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
969 olsr_cnf->exit_value = EXIT_FAILURE;
970 kill(getpid(), SIGINT);
977 ifp->ip_addr.v6 = ifp->int6_addr.sin6_addr;
980 *We create one socket for each interface and bind
981 *the socket to it. This to ensure that we can control
982 *on what interface the message is transmitted
985 ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
987 join_mcast(ifp, ifp->olsr_socket);
989 if (ifp->olsr_socket < 0)
991 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
992 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
993 olsr_cnf->exit_value = EXIT_FAILURE;
994 kill(getpid(), SIGINT);
999 set_buffer_timer(ifp);
1001 /* Register socket */
1002 add_olsr_socket(ifp->olsr_socket, &olsr_input);
1007 if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
1009 perror("setsockopt(SO_PRIORITY)");
1010 olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
1012 if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)
1014 perror("setsockopt(IP_TOS)");
1015 olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
1020 *Initialize sequencenumber as a random 16bit value
1022 ifp->olsr_seqnum = random() & 0xFFFF;
1025 * Set main address if this is the only interface
1027 memset(&null_addr, 0, olsr_cnf->ipsize);
1028 if(ipequal(&null_addr, &olsr_cnf->main_addr))
1030 struct ipaddr_str buf;
1031 olsr_cnf->main_addr = ifp->ip_addr;
1032 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
1033 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
1037 * Register scheduled functions
1040 olsr_register_scheduler_event(olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello,
1042 iface->cnf->hello_params.emission_interval,
1045 olsr_register_scheduler_event(olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc,
1047 iface->cnf->tc_params.emission_interval,
1050 olsr_register_scheduler_event(&generate_mid,
1052 iface->cnf->mid_params.emission_interval,
1055 olsr_register_scheduler_event(&generate_hna,
1057 iface->cnf->hna_params.emission_interval,
1061 /* Recalculate max jitter */
1063 if((olsr_cnf->max_jitter == 0) ||
1064 ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter)) {
1065 olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
1068 /* Recalculate max topology hold time */
1069 if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval) {
1070 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
1072 ifp->hello_etime = iface->cnf->hello_params.emission_interval;
1073 ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
1074 ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
1075 ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
1076 ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
1080 *Call possible ifchange functions registered by plugins
1082 run_ifchg_cbs(ifp, IFCHG_IF_ADD);