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.
42 #if defined __FreeBSD__ || 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 */
75 set_flag(char *ifname, short flag __attribute__((unused)))
79 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
82 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
84 fprintf(stderr,"ioctl (get interface flags)");
88 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
90 //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
92 if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)))
95 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
97 if(ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
99 fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
111 check_interface_updates(void *foo __attribute__((unused)))
113 struct olsr_if *tmp_if;
116 OLSR_PRINTF(3, "Checking for updates in the interface set\n");
119 for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
121 if(tmp_if->host_emul)
124 if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
127 if(!tmp_if->cnf->autodetect_chg)
130 /* Don't check this interface */
131 OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name);
136 if(tmp_if->configured)
138 chk_if_changed(tmp_if);
142 chk_if_up(tmp_if, 3);
150 * Checks if an initialized interface is changed
151 * that is if it has been set down or the address
154 *@param iface the olsr_if struct describing the interface
157 chk_if_changed(struct olsr_if *iface)
159 struct interface *ifp, *tmp_ifp;
161 struct sockaddr_in6 tmp_saddr6;
166 OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
176 /* Should not happen */
177 iface->configured = 0;
181 memset(&ifr, 0, sizeof(struct ifreq));
182 strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
185 /* Get flags (and check if interface exists) */
186 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
188 OLSR_PRINTF(3, "No such interface: %s\n", iface->name);
189 goto remove_interface;
192 ifp->int_flags = ifr.ifr_flags;
195 * First check if the interface is set DOWN
198 if ((ifp->int_flags & IFF_UP) == 0)
200 OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name);
201 goto remove_interface;
205 * We do all the interface type checks over.
206 * This is because the interface might be a PCMCIA card. Therefore
207 * It might not be the same physical interface as we configured earlier.
210 /* Check broadcast */
211 if ((olsr_cnf->ip_version == AF_INET) &&
212 !iface->cnf->ipv4_broadcast.v4.s_addr && /* Skip if fixed bcast */
213 (!(ifp->int_flags & IFF_BROADCAST)))
215 OLSR_PRINTF(3, "\tNo broadcast - removing\n");
216 goto remove_interface;
219 if (ifp->int_flags & IFF_LOOPBACK)
221 OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n");
222 goto remove_interface;
225 ifp->is_hcif = OLSR_FALSE;
227 /* trying to detect if interface is wireless. */
228 ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
230 /* Set interface metric */
231 if(iface->cnf->weight.fixed)
232 ifp->int_metric = iface->cnf->weight.value;
234 ifp->int_metric = calculate_if_metric(ifr.ifr_name);
237 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
241 ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
243 if(ifp->int_mtu != ifr.ifr_mtu)
245 ifp->int_mtu = ifr.ifr_mtu;
246 /* Create new outputbuffer */
247 net_remove_buffer(ifp); /* Remove old */
253 /* Get interface index */
254 ifp->if_index = if_nametoindex(ifr.ifr_name);
257 * Now check if the IP has changed
261 if(olsr_cnf->ip_version == AF_INET6)
263 #if !defined(NODEBUG) && defined(DEBUG)
264 struct ipaddr_str buf;
266 /* Get interface address */
268 if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0)
270 if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
271 OLSR_PRINTF(3, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
273 OLSR_PRINTF(3, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
276 goto remove_interface;
280 OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
283 if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0)
286 struct ipaddr_str buf;
288 OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name);
289 OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&buf, &ifp->int6_addr.sin6_addr));
290 OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
292 /* Check main addr */
293 if(memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0)
295 /* Update main addr */
296 memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
300 memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
301 memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
303 run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
313 struct ipaddr_str buf;
314 /* Check interface address (IPv4)*/
315 if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0)
317 OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n");
318 goto remove_interface;
322 OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
325 if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
326 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
327 olsr_cnf->ipsize) != 0)
330 OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name);
331 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_addr.sin_addr));
332 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
334 ifp->int_addr = *(struct sockaddr_in *)&ifr.ifr_addr;
336 if(memcmp(&olsr_cnf->main_addr,
338 olsr_cnf->ipsize) == 0)
340 OLSR_PRINTF(1, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
341 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
342 memcpy(&olsr_cnf->main_addr,
343 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
347 memcpy(&ifp->ip_addr,
348 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr,
355 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0)
357 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
358 goto remove_interface;
362 OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
365 if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
366 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr,
367 olsr_cnf->ipsize) != 0)
370 struct ipaddr_str buf;
373 OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
374 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_netmask.sin_addr));
375 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
377 ifp->int_netmask = *(struct sockaddr_in *)&ifr.ifr_netmask;
382 if(!iface->cnf->ipv4_broadcast.v4.s_addr)
384 /* Check broadcast address */
385 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0)
387 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
388 goto remove_interface;
392 OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
395 if(ifp->int_broadaddr.sin_addr.s_addr != ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr)
398 struct ipaddr_str buf;
401 OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
402 OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_broadaddr.sin_addr));
403 OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
405 ifp->int_broadaddr = *(struct sockaddr_in *)&ifr.ifr_broadaddr;
412 run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
418 OLSR_PRINTF(1, "Removing interface %s\n", iface->name);
419 olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
421 del_if_link_entries(&ifp->ip_addr);
424 *Call possible ifchange functions registered by plugins
426 run_ifchg_cbs(ifp, IFCHG_IF_REMOVE);
431 ifnet = ifp->int_next;
436 while(tmp_ifp->int_next != ifp)
438 tmp_ifp = tmp_ifp->int_next;
440 tmp_ifp->int_next = ifp->int_next;
444 /* Remove output buffer */
445 net_remove_buffer(ifp);
447 /* Check main addr */
448 if(ipequal(&olsr_cnf->main_addr, &ifp->ip_addr))
452 /* No more interfaces */
453 memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
454 OLSR_PRINTF(1, "No more interfaces...\n");
458 struct ipaddr_str buf;
459 olsr_cnf->main_addr = ifnet->ip_addr;
460 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
461 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
467 * Deregister scheduled functions
470 if (olsr_cnf->lq_level == 0)
472 olsr_remove_scheduler_event(&generate_hello,
474 iface->cnf->hello_params.emission_interval,
477 olsr_remove_scheduler_event(&generate_tc,
479 iface->cnf->tc_params.emission_interval,
486 olsr_remove_scheduler_event(&olsr_output_lq_hello,
488 iface->cnf->hello_params.emission_interval,
491 olsr_remove_scheduler_event(&olsr_output_lq_tc,
493 iface->cnf->tc_params.emission_interval,
498 olsr_remove_scheduler_event(&generate_mid,
500 iface->cnf->mid_params.emission_interval,
503 olsr_remove_scheduler_event(&generate_hna,
505 iface->cnf->hna_params.emission_interval,
511 iface->configured = 0;
512 iface->interf = NULL;
513 /* Close olsr socket */
514 close(ifp->olsr_socket);
515 remove_olsr_socket(ifp->olsr_socket, &olsr_input);
521 if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
523 OLSR_PRINTF(1, "No more active interfaces - exiting.\n");
524 olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
525 olsr_cnf->exit_value = EXIT_FAILURE;
526 kill(getpid(), SIGINT);
534 * Initializes the special interface used in
535 * host-client emulation
538 add_hemu_if(struct olsr_if *iface)
540 struct interface *ifp;
541 union olsr_ip_addr null_addr;
543 struct ipaddr_str buf;
545 if(!iface->host_emul)
548 ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
550 memset(ifp, 0, sizeof (struct interface));
552 iface->configured = OLSR_TRUE;
555 ifp->is_hcif = OLSR_TRUE;
556 ifp->int_name = olsr_malloc(strlen("hcif01") + 1, "Interface update 3");
559 strcpy(ifp->int_name, "hcif01");
561 OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
563 OLSR_PRINTF(1, " Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
565 OLSR_PRINTF(1, " NB! This is a emulated interface\n that does not exist in the kernel!\n");
567 ifp->int_next = ifnet;
570 memset(&null_addr, 0, olsr_cnf->ipsize);
571 if(ipequal(&null_addr, &olsr_cnf->main_addr))
573 olsr_cnf->main_addr = iface->hemu_ip;
574 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
575 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
578 ifp->int_mtu = OLSR_DEFAULT_MTU;
580 ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
586 if(olsr_cnf->ip_version == AF_INET)
588 struct sockaddr_in sin;
590 memset(&sin, 0, sizeof(sin));
592 sin.sin_family = AF_INET;
593 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
594 sin.sin_port = htons(10150);
597 ifp->ip_addr.v4 = iface->hemu_ip.v4;
599 memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
602 *We create one socket for each interface and bind
603 *the socket to it. This to ensure that we can control
604 *on what interface the message is transmitted
607 ifp->olsr_socket = gethemusocket(&sin);
609 if (ifp->olsr_socket < 0)
611 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
612 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
613 olsr_cnf->exit_value = EXIT_FAILURE;
614 kill(getpid(), SIGINT);
621 memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
625 *We create one socket for each interface and bind
626 *the socket to it. This to ensure that we can control
627 *on what interface the message is transmitted
630 ifp->olsr_socket = gethcsocket6(&addrsock6, BUFSPACE, ifp->int_name);
632 join_mcast(ifp, ifp->olsr_socket);
634 if (ifp->olsr_socket < 0)
636 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
637 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
638 olsr_cnf->exit_value = EXIT_FAILURE;
639 kill(getpid(), SIGINT);
645 /* Send IP as first 4/16 bytes on socket */
646 memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
647 addr[0] = htonl(addr[0]);
648 addr[1] = htonl(addr[1]);
649 addr[2] = htonl(addr[2]);
650 addr[3] = htonl(addr[3]);
652 if(send(ifp->olsr_socket, addr , olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
654 fprintf(stderr, "Error sending IP!");
657 /* Register socket */
658 add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
661 if (olsr_cnf->lq_level == 0)
663 olsr_register_scheduler_event(&generate_hello,
665 iface->cnf->hello_params.emission_interval,
668 olsr_register_scheduler_event(&generate_tc,
670 iface->cnf->tc_params.emission_interval,
677 olsr_register_scheduler_event(&olsr_output_lq_hello,
679 iface->cnf->hello_params.emission_interval,
682 olsr_register_scheduler_event(&olsr_output_lq_tc,
684 iface->cnf->tc_params.emission_interval,
689 olsr_register_scheduler_event(&generate_mid,
691 iface->cnf->mid_params.emission_interval,
694 olsr_register_scheduler_event(&generate_hna,
696 iface->cnf->hna_params.emission_interval,
700 /* Recalculate max jitter */
702 if((olsr_cnf->max_jitter == 0) ||
703 ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
704 olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
706 /* Recalculate max topology hold time */
707 if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
708 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
710 ifp->hello_etime = iface->cnf->hello_params.emission_interval;
711 ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
712 ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
713 ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
714 ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
719 static char basenamestr[32];
720 static const char* if_basename(const char* name);
721 static const char* if_basename(const char* name)
723 char *p = strchr(name, ':');
724 if (NULL == p || p - name >= (int)(sizeof(basenamestr) / sizeof(basenamestr[0]) - 1)) {
727 memcpy(basenamestr, name, p - name);
728 basenamestr[p - name] = 0;
733 * Initializes a interface described by iface,
734 * if it is set up and is of the correct type.
736 *@param iface the olsr_if struct describing the interface
737 *@param so the socket to use for ioctls
741 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__((unused)))
743 struct interface ifs, *ifp;
745 union olsr_ip_addr null_addr;
747 int precedence = IPTOS_PREC(olsr_cnf->tos);
748 int tos_bits = IPTOS_TOS(olsr_cnf->tos);
754 memset(&ifr, 0, sizeof(struct ifreq));
755 strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
757 OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
759 /* Get flags (and check if interface exists) */
760 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0)
762 OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
766 memset(&ifs.netbuf, 0, sizeof(struct olsr_netbuf));
767 ifs.int_flags = ifr.ifr_flags;
770 if ((ifs.int_flags & IFF_UP) == 0)
772 OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n");
776 /* Check broadcast */
777 if ((olsr_cnf->ip_version == AF_INET) &&
778 !iface->cnf->ipv4_broadcast.v4.s_addr && /* Skip if fixed bcast */
779 (!(ifs.int_flags & IFF_BROADCAST)))
781 OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
786 if (ifs.int_flags & IFF_LOOPBACK)
788 OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
792 ifs.is_hcif = OLSR_FALSE;
794 /* trying to detect if interface is wireless. */
795 ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
798 OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
800 OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
804 if(olsr_cnf->ip_version == AF_INET6)
806 /* Get interface address */
808 struct ipaddr_str buf;
810 if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
812 if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
813 OLSR_PRINTF(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
815 OLSR_PRINTF(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
820 OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
823 ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) ?
824 iface->cnf->ipv6_multi_site.v6 :
825 iface->cnf->ipv6_multi_glbl.v6;
826 /* Set address family */
827 ifs.int6_multaddr.sin6_family = AF_INET6;
829 ifs.int6_multaddr.sin6_port = htons(OLSRPORT);
832 ifs.int6_multaddr.sin6_scope_id = 0;
835 OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
841 /* Get interface address (IPv4)*/
842 if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0)
844 OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
848 ifs.int_addr = *(struct sockaddr_in *)&ifr.ifr_addr;
852 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0)
854 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
858 ifs.int_netmask = *(struct sockaddr_in *)&ifr.ifr_netmask;
860 /* Find broadcast address */
861 if(iface->cnf->ipv4_broadcast.v4.s_addr)
863 /* Specified broadcast */
864 memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
865 memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr,
866 &iface->cnf->ipv4_broadcast.v4,
872 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0)
874 olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
878 ifs.int_broadaddr = *(struct sockaddr_in *)&ifr.ifr_broadaddr;
881 /* Deactivate IP spoof filter */
882 deactivate_spoof(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
884 /* Disable ICMP redirects */
885 disable_redirects(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
890 /* Get interface index */
892 ifs.if_index = if_nametoindex(ifr.ifr_name);
894 /* Set interface metric */
895 if(iface->cnf->weight.fixed)
896 ifs.int_metric = iface->cnf->weight.value;
898 ifs.int_metric = calculate_if_metric(ifr.ifr_name);
899 OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
902 if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
903 ifs.int_mtu = OLSR_DEFAULT_MTU;
905 ifs.int_mtu = ifr.ifr_mtu;
907 ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
912 net_add_buffer(&ifs);
914 OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
916 olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
917 OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_index);
919 if(olsr_cnf->ip_version == AF_INET)
922 struct ipaddr_str buf;
924 OLSR_PRINTF(1, "\tAddress:%s\n", ip4_to_string(&buf, ifs.int_addr.sin_addr));
925 OLSR_PRINTF(1, "\tNetmask:%s\n", ip4_to_string(&buf, ifs.int_netmask.sin_addr));
926 OLSR_PRINTF(1, "\tBroadcast address:%s\n", ip4_to_string(&buf, ifs.int_broadaddr.sin_addr));
931 struct ipaddr_str buf;
933 OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
934 OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
937 ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
939 ifp->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
941 iface->configured = 1;
944 memcpy(ifp, &ifs, sizeof(struct interface));
946 ifp->gen_properties = NULL;
947 ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
949 strcpy(ifp->int_name, if_basename(ifr.ifr_name));
950 /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
951 ifp->int_next = ifnet;
954 if(olsr_cnf->ip_version == AF_INET)
957 ifp->ip_addr.v4 = ifp->int_addr.sin_addr;
959 *We create one socket for each interface and bind
960 *the socket to it. This to ensure that we can control
961 *on what interface the message is transmitted
964 ifp->olsr_socket = getsocket(BUFSPACE, ifp->int_name);
966 if (ifp->olsr_socket < 0)
968 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
969 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
970 olsr_cnf->exit_value = EXIT_FAILURE;
971 kill(getpid(), SIGINT);
978 ifp->ip_addr.v6 = ifp->int6_addr.sin6_addr;
981 *We create one socket for each interface and bind
982 *the socket to it. This to ensure that we can control
983 *on what interface the message is transmitted
986 ifp->olsr_socket = getsocket6(BUFSPACE, ifp->int_name);
988 join_mcast(ifp, ifp->olsr_socket);
990 if (ifp->olsr_socket < 0)
992 fprintf(stderr, "Could not initialize socket... exiting!\n\n");
993 olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
994 olsr_cnf->exit_value = EXIT_FAILURE;
995 kill(getpid(), SIGINT);
1000 set_buffer_timer(ifp);
1002 /* Register socket */
1003 add_olsr_socket(ifp->olsr_socket, &olsr_input);
1008 if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
1010 perror("setsockopt(SO_PRIORITY)");
1011 olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
1013 if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)
1015 perror("setsockopt(IP_TOS)");
1016 olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
1021 *Initialize sequencenumber as a random 16bit value
1023 ifp->olsr_seqnum = random() & 0xFFFF;
1026 * Set main address if this is the only interface
1028 memset(&null_addr, 0, olsr_cnf->ipsize);
1029 if(ipequal(&null_addr, &olsr_cnf->main_addr))
1031 struct ipaddr_str buf;
1032 olsr_cnf->main_addr = ifp->ip_addr;
1033 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
1034 olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
1038 * Register scheduled functions
1041 olsr_register_scheduler_event(olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello,
1043 iface->cnf->hello_params.emission_interval,
1046 olsr_register_scheduler_event(olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc,
1048 iface->cnf->tc_params.emission_interval,
1051 olsr_register_scheduler_event(&generate_mid,
1053 iface->cnf->mid_params.emission_interval,
1056 olsr_register_scheduler_event(&generate_hna,
1058 iface->cnf->hna_params.emission_interval,
1062 /* Recalculate max jitter */
1064 if((olsr_cnf->max_jitter == 0) ||
1065 ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter)) {
1066 olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
1069 /* Recalculate max topology hold time */
1070 if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval) {
1071 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
1073 ifp->hello_etime = iface->cnf->hello_params.emission_interval;
1074 ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
1075 ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
1076 ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
1077 ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
1081 *Call possible ifchange functions registered by plugins
1083 run_ifchg_cbs(ifp, IFCHG_IF_ADD);