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.43 2007/02/04 23:36:35 bernd67 Exp $
43 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
44 #define ifr_netmask ifr_addr
47 #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>
75 int bufspace = 127*1024; /* max. input buffer size to request */
79 set_flag(char *ifname, short flag)
83 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
86 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
88 fprintf(stderr,"ioctl (get interface flags)");
92 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
94 //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
96 if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)))
99 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
101 if(ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
103 fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
115 check_interface_updates(void *foo)
117 struct olsr_if *tmp_if;
120 OLSR_PRINTF(3, "Checking for updates in the interface set\n")
123 for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
125 if(tmp_if->host_emul)
128 if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
131 if(!tmp_if->cnf->autodetect_chg)
134 /* Don't check this interface */
135 OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name)
140 if(tmp_if->configured)
142 chk_if_changed(tmp_if);
146 chk_if_up(tmp_if, 3);
154 * Checks if an initialized interface is changed
155 * that is if it has been set down or the address
158 *@param iface the olsr_if struct describing the interface
161 chk_if_changed(struct olsr_if *iface)
163 struct interface *ifp, *tmp_ifp;
165 struct sockaddr_in6 tmp_saddr6;
170 OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name)
180 /* Should not happen */
181 iface->configured = 0;
185 memset(&ifr, 0, sizeof(struct ifreq));
186 strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
189 /* Get flags (and check if interface exists) */
190 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
192 OLSR_PRINTF(3, "No such interface: %s\n", iface->name)
193 goto remove_interface;
196 ifp->int_flags = ifr.ifr_flags;
199 * First check if the interface is set DOWN
202 if ((ifp->int_flags & IFF_UP) == 0)
204 OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name)
205 goto remove_interface;
209 * We do all the interface type checks over.
210 * This is because the interface might be a PCMCIA card. Therefore
211 * It might not be the same physical interface as we configured earlier.
214 /* Check broadcast */
215 if ((olsr_cnf->ip_version == AF_INET) &&
216 !iface->cnf->ipv4_broadcast.v4 && /* Skip if fixed bcast */
217 (!(ifp->int_flags & IFF_BROADCAST)))
219 OLSR_PRINTF(3, "\tNo broadcast - removing\n")
220 goto remove_interface;
223 if (ifp->int_flags & IFF_LOOPBACK)
225 OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n")
226 goto remove_interface;
229 ifp->is_hcif = OLSR_FALSE;
231 /* trying to detect if interface is wireless. */
232 ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
234 /* Set interface metric */
235 if(iface->cnf->weight.fixed)
236 ifp->int_metric = iface->cnf->weight.value;
238 ifp->int_metric = calculate_if_metric(ifr.ifr_name);
241 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
245 ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
247 if(ifp->int_mtu != ifr.ifr_mtu)
249 ifp->int_mtu = ifr.ifr_mtu;
250 /* Create new outputbuffer */
251 net_remove_buffer(ifp); /* Remove old */
257 /* Get interface index */
258 ifp->if_index = if_nametoindex(ifr.ifr_name);
261 * Now check if the IP has changed
265 if(olsr_cnf->ip_version == AF_INET6)
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(&tmp_saddr6.sin6_addr))
284 if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0)
286 OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name)
287 OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&ifp->int6_addr.sin6_addr))
288 OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr))
290 /* Check main addr */
291 if(memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0)
293 /* Update main addr */
294 memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
298 memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
299 memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
301 run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
311 /* Check interface address (IPv4)*/
312 if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0)
314 OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n")
315 goto remove_interface;
319 OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr_to_string(&ifr.ifr_addr))
322 if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
323 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
324 olsr_cnf->ipsize) != 0)
327 OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name)
328 OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr))
329 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr))
331 if(memcmp(&olsr_cnf->main_addr,
332 &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
333 olsr_cnf->ipsize) == 0)
335 OLSR_PRINTF(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr))
336 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr));
337 memcpy(&olsr_cnf->main_addr,
338 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
342 ifp->int_addr = ifr.ifr_addr;
343 memcpy(&ifp->ip_addr,
344 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
351 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0)
353 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
354 goto remove_interface;
358 OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr_to_string(&ifr.ifr_netmask))
361 if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
362 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr,
363 olsr_cnf->ipsize) != 0)
366 OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name)
367 OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_netmask))
368 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_netmask))
370 ifp->int_netmask = ifr.ifr_netmask;
375 if(!iface->cnf->ipv4_broadcast.v4)
377 /* Check broadcast address */
378 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0)
380 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
381 goto remove_interface;
385 OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr))
388 if(memcmp(&((struct sockaddr_in *)&ifp->int_broadaddr)->sin_addr.s_addr,
389 &((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr,
390 olsr_cnf->ipsize) != 0)
394 OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name)
395 OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_broadaddr))
396 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr))
398 ifp->int_broadaddr = ifr.ifr_broadaddr;
405 run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
411 OLSR_PRINTF(1, "Removing interface %s\n", iface->name)
412 olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
414 del_if_link_entries(&ifp->ip_addr);
417 *Call possible ifchange functions registered by plugins
419 run_ifchg_cbs(ifp, IFCHG_IF_REMOVE);
424 ifnet = ifp->int_next;
429 while(tmp_ifp->int_next != ifp)
431 tmp_ifp = tmp_ifp->int_next;
433 tmp_ifp->int_next = ifp->int_next;
437 /* Remove output buffer */
438 net_remove_buffer(ifp);
440 /* Check main addr */
441 if(COMP_IP(&olsr_cnf->main_addr, &ifp->ip_addr))
445 /* No more interfaces */
446 memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
447 OLSR_PRINTF(1, "No more interfaces...\n")
451 COPY_IP(&olsr_cnf->main_addr, &ifnet->ip_addr);
452 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
453 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
459 * Deregister scheduled functions
462 if (olsr_cnf->lq_level == 0)
464 olsr_remove_scheduler_event(&generate_hello,
466 iface->cnf->hello_params.emission_interval,
469 olsr_remove_scheduler_event(&generate_tc,
471 iface->cnf->tc_params.emission_interval,
478 olsr_remove_scheduler_event(&olsr_output_lq_hello,
480 iface->cnf->hello_params.emission_interval,
483 olsr_remove_scheduler_event(&olsr_output_lq_tc,
485 iface->cnf->tc_params.emission_interval,
490 olsr_remove_scheduler_event(&generate_mid,
492 iface->cnf->mid_params.emission_interval,
495 olsr_remove_scheduler_event(&generate_hna,
497 iface->cnf->hna_params.emission_interval,
503 iface->configured = 0;
504 iface->interf = NULL;
505 /* Close olsr socket */
506 close(ifp->olsr_socket);
507 remove_olsr_socket(ifp->olsr_socket, &olsr_input);
509 libnet_destroy(ifp->libnet_ctx);
516 if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
518 OLSR_PRINTF(1, "No more active interfaces - exiting.\n")
519 olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
520 olsr_cnf->exit_value = EXIT_FAILURE;
521 kill(getpid(), SIGINT);
529 * Initializes the special interface used in
530 * host-client emulation
533 add_hemu_if(struct olsr_if *iface)
535 struct interface *ifp;
536 union olsr_ip_addr null_addr;
539 if(!iface->host_emul)
542 ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
544 memset(ifp, 0, sizeof (struct interface));
546 iface->configured = OLSR_TRUE;
549 ifp->is_hcif = OLSR_TRUE;
550 ifp->int_name = olsr_malloc(strlen("hcif01") + 1, "Interface update 3");
553 strcpy(ifp->int_name, "hcif01");
555 OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name)
557 OLSR_PRINTF(1, " Address:%s\n", olsr_ip_to_string(&iface->hemu_ip));
559 OLSR_PRINTF(1, " Index:%d\n", iface->index);
561 OLSR_PRINTF(1, " NB! This is a emulated interface\n that does not exist in the kernel!\n");
563 ifp->int_next = ifnet;
566 memset(&null_addr, 0, olsr_cnf->ipsize);
567 if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
569 COPY_IP(&olsr_cnf->main_addr, &iface->hemu_ip);
570 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
571 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
574 /* setting the interfaces number*/
575 ifp->if_nr = iface->index;
577 ifp->int_mtu = OLSR_DEFAULT_MTU;
579 ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
585 if(olsr_cnf->ip_version == AF_INET)
587 struct sockaddr_in sin;
589 memset(&sin, 0, sizeof(sin));
591 sin.sin_family = AF_INET;
592 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
593 sin.sin_port = htons(10150);
596 ifp->ip_addr.v4 = iface->hemu_ip.v4;
598 memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
601 *We create one socket for each interface and bind
602 *the socket to it. This to ensure that we can control
603 *on what interface the message is transmitted
606 ifp->olsr_socket = gethemusocket(&sin);
608 if (ifp->olsr_socket < 0)
610 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
611 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
612 olsr_cnf->exit_value = EXIT_FAILURE;
613 kill(getpid(), SIGINT);
620 memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
624 *We create one socket for each interface and bind
625 *the socket to it. This to ensure that we can control
626 *on what interface the message is transmitted
629 ifp->olsr_socket = gethcsocket6(&addrsock6, bufspace, ifp->int_name);
631 join_mcast(ifp, ifp->olsr_socket);
633 if (ifp->olsr_socket < 0)
635 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
636 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
637 olsr_cnf->exit_value = EXIT_FAILURE;
638 kill(getpid(), SIGINT);
644 /* Send IP as first 4/16 bytes on socket */
645 memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
646 addr[0] = htonl(addr[0]);
647 addr[1] = htonl(addr[1]);
648 addr[2] = htonl(addr[2]);
649 addr[3] = htonl(addr[3]);
651 if(send(ifp->olsr_socket, addr , olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
653 fprintf(stderr, "Error sending IP!");
656 /* Register socket */
657 add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
660 if (olsr_cnf->lq_level == 0)
662 olsr_register_scheduler_event(&generate_hello,
664 iface->cnf->hello_params.emission_interval,
667 olsr_register_scheduler_event(&generate_tc,
669 iface->cnf->tc_params.emission_interval,
676 olsr_register_scheduler_event(&olsr_output_lq_hello,
678 iface->cnf->hello_params.emission_interval,
681 olsr_register_scheduler_event(&olsr_output_lq_tc,
683 iface->cnf->tc_params.emission_interval,
688 olsr_register_scheduler_event(&generate_mid,
690 iface->cnf->mid_params.emission_interval,
693 olsr_register_scheduler_event(&generate_hna,
695 iface->cnf->hna_params.emission_interval,
699 /* Recalculate max jitter */
701 if((olsr_cnf->max_jitter == 0) ||
702 ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
703 olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
705 /* Recalculate max topology hold time */
706 if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
707 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
709 ifp->hello_etime = iface->cnf->hello_params.emission_interval;
710 ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
711 ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
712 ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
713 ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
718 static char basename[32];
719 char* if_basename(char* name);
720 char* if_basename(char* name)
722 char *p = strchr(name, ':');
723 if (0 == p || p - name >= (int)(sizeof(basename) / sizeof(basename[0]) - 1)) return name;
724 memcpy(basename, name, p - name);
725 basename[p - name] = 0;
730 * Initializes a interface described by iface,
731 * if it is set up and is of the correct type.
733 *@param iface the olsr_if struct describing the interface
734 *@param so the socket to use for ioctls
738 chk_if_up(struct olsr_if *iface, int debuglvl)
740 struct interface ifs, *ifp;
742 union olsr_ip_addr null_addr;
744 int precedence = IPTOS_PREC(olsr_cnf->tos);
745 int tos_bits = IPTOS_TOS(olsr_cnf->tos);
751 memset(&ifr, 0, sizeof(struct ifreq));
752 strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
754 OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name)
756 /* Get flags (and check if interface exists) */
757 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
759 OLSR_PRINTF(debuglvl, "\tNo such interface!\n")
763 memset(&ifs.netbuf, 0, sizeof(struct olsr_netbuf));
764 ifs.int_flags = ifr.ifr_flags;
767 if ((ifs.int_flags & IFF_UP) == 0)
769 OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n")
773 /* Check broadcast */
774 if ((olsr_cnf->ip_version == AF_INET) &&
775 !iface->cnf->ipv4_broadcast.v4 && /* Skip if fixed bcast */
776 (!(ifs.int_flags & IFF_BROADCAST)))
778 OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n")
783 if (ifs.int_flags & IFF_LOOPBACK)
785 OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n")
789 ifs.is_hcif = OLSR_FALSE;
791 /* trying to detect if interface is wireless. */
792 ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
795 OLSR_PRINTF(debuglvl, "\tWireless interface detected\n")
797 OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n")
801 if(olsr_cnf->ip_version == AF_INET6)
803 /* Get interface address */
805 if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
807 if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
808 OLSR_PRINTF(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name)
810 OLSR_PRINTF(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name)
815 OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr))
818 ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) ?
819 iface->cnf->ipv6_multi_site.v6 :
820 iface->cnf->ipv6_multi_glbl.v6;
821 /* Set address family */
822 ifs.int6_multaddr.sin6_family = AF_INET6;
824 ifs.int6_multaddr.sin6_port = htons(OLSRPORT);
826 OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr))
832 /* Get interface address (IPv4)*/
833 if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0)
835 OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n")
839 ifs.int_addr = ifr.ifr_addr;
843 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0)
845 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
849 ifs.int_netmask = ifr.ifr_netmask;
851 /* Find broadcast address */
852 if(iface->cnf->ipv4_broadcast.v4)
854 /* Specified broadcast */
855 memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
856 memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr,
857 &iface->cnf->ipv4_broadcast.v4,
863 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0)
865 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
869 ifs.int_broadaddr = ifr.ifr_broadaddr;
872 /* Deactivate IP spoof filter */
873 deactivate_spoof(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
875 /* Disable ICMP redirects */
876 disable_redirects(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
881 /* Get interface index */
883 ifs.if_index = if_nametoindex(ifr.ifr_name);
885 /* Set interface metric */
886 if(iface->cnf->weight.fixed)
887 ifs.int_metric = iface->cnf->weight.value;
889 ifs.int_metric = calculate_if_metric(ifr.ifr_name);
890 OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric)
892 /* setting the interfaces number*/
893 ifs.if_nr = iface->index;
897 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
898 ifs.int_mtu = OLSR_DEFAULT_MTU;
900 ifs.int_mtu = ifr.ifr_mtu;
902 ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
907 net_add_buffer(&ifs);
909 OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu)
911 olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
912 OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_nr)
914 if(olsr_cnf->ip_version == AF_INET)
916 OLSR_PRINTF(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr))
917 OLSR_PRINTF(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask))
918 OLSR_PRINTF(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr))
922 OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr))
923 OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr))
926 ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
928 iface->configured = 1;
931 memcpy(ifp, &ifs, sizeof(struct interface));
934 ifp->libnet_ctx = NULL;
936 ifp->gen_properties = NULL;
937 ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
939 strcpy(ifp->int_name, if_basename(ifr.ifr_name));
940 /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
941 ifp->int_next = ifnet;
944 if(olsr_cnf->ip_version == AF_INET)
947 ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
949 *We create one socket for each interface and bind
950 *the socket to it. This to ensure that we can control
951 *on what interface the message is transmitted
954 ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
956 if (ifp->olsr_socket < 0)
958 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
959 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
960 olsr_cnf->exit_value = EXIT_FAILURE;
961 kill(getpid(), SIGINT);
968 memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize);
972 *We create one socket for each interface and bind
973 *the socket to it. This to ensure that we can control
974 *on what interface the message is transmitted
977 ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
979 join_mcast(ifp, ifp->olsr_socket);
981 if (ifp->olsr_socket < 0)
983 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
984 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
985 olsr_cnf->exit_value = EXIT_FAILURE;
986 kill(getpid(), SIGINT);
993 ifp->libnet_ctx = libnet_init((olsr_cnf->ip_version == AF_INET) ?
994 LIBNET_RAW4 : LIBNET_RAW6,
995 ifp->int_name, get_libnet_errbuf());
997 ifp->libnet_ctx = libnet_init(LIBNET_LINK, ifp->int_name, get_libnet_errbuf());
1000 if(ifp->libnet_ctx == NULL)
1002 fprintf(stderr, "Could not initialize libnet... exiting!\n\n");
1003 olsr_syslog(OLSR_LOG_ERR, "Could not initialize libnet... exiting!\n\n");
1004 olsr_cnf->exit_value = EXIT_FAILURE;
1005 kill(getpid(), SIGINT);
1008 set_buffer_timer(ifp);
1010 /* Register socket */
1011 add_olsr_socket(ifp->olsr_socket, &olsr_input);
1016 if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
1018 perror("setsockopt(SO_PRIORITY)");
1019 olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
1021 if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)
1023 perror("setsockopt(IP_TOS)");
1024 olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
1029 *Initialize sequencenumber as a random 16bit value
1031 ifp->olsr_seqnum = random() & 0xFFFF;
1034 * Set main address if this is the only interface
1036 memset(&null_addr, 0, olsr_cnf->ipsize);
1037 if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
1039 COPY_IP(&olsr_cnf->main_addr, &ifp->ip_addr);
1040 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
1041 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
1045 * Register scheduled functions
1048 if (olsr_cnf->lq_level == 0)
1050 olsr_register_scheduler_event(&generate_hello,
1052 iface->cnf->hello_params.emission_interval,
1055 olsr_register_scheduler_event(&generate_tc,
1057 iface->cnf->tc_params.emission_interval,
1064 olsr_register_scheduler_event(&olsr_output_lq_hello,
1066 iface->cnf->hello_params.emission_interval,
1069 olsr_register_scheduler_event(&olsr_output_lq_tc,
1071 iface->cnf->tc_params.emission_interval,
1076 olsr_register_scheduler_event(&generate_mid,
1078 iface->cnf->mid_params.emission_interval,
1081 olsr_register_scheduler_event(&generate_hna,
1083 iface->cnf->hna_params.emission_interval,
1087 /* Recalculate max jitter */
1089 if((olsr_cnf->max_jitter == 0) ||
1090 ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
1091 olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
1093 /* Recalculate max topology hold time */
1094 if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
1095 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
1097 ifp->hello_etime = iface->cnf->hello_params.emission_interval;
1098 ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
1099 ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
1100 ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
1101 ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
1105 *Call possible ifchange functions registered by plugins
1107 run_ifchg_cbs(ifp, IFCHG_IF_ADD);