Fix for bug where main address is not updated when IP change is detected
[olsrd.git] / src / unix / ifnet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
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 
15  *   distribution.
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.
19  *
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.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
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.
38  *
39  * $Id: ifnet.c,v 1.36 2006/04/11 14:59:20 kattemat Exp $
40  */
41
42
43 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
44 #define ifr_netmask ifr_addr
45 #endif
46
47 #include "interfaces.h"
48 #include "ifnet.h"
49 #include "defs.h"
50 #include "olsr.h"
51 #include "net_os.h"
52 #include "net_olsr.h"
53 #include "socket_parser.h"
54 #include "parser.h"
55 #include "scheduler.h"
56 #include "generate_msg.h"
57 #include "mantissa.h"
58 #include "lq_packet.h"
59 #include "log.h"
60 #include <signal.h>
61 #include <sys/types.h>
62 #include <net/if.h>
63 #include <net/if_arp.h>
64 #include <netinet/in_systm.h>
65 #include <netinet/ip.h>
66 #include <arpa/inet.h>
67 #include <netdb.h>
68 #include <unistd.h>
69
70 #ifdef USE_LIBNET
71 #include <libnet.h>
72 #endif
73
74 int bufspace = 127*1024;        /* max. input buffer size to request */
75
76
77 int
78 set_flag(char *ifname, short flag)
79 {
80   struct ifreq ifr;
81
82   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
83
84   /* Get flags */
85   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
86     {
87       fprintf(stderr,"ioctl (get interface flags)");
88       return -1;
89     }
90
91   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
92   
93   //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
94
95   if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)))
96     {
97       /* Add UP */
98       ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
99       /* Set flags + UP */
100       if(ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
101         {
102           fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
103           return -1;
104         }
105     }
106   return 1;
107
108 }
109
110
111
112
113 void
114 check_interface_updates(void *foo)
115 {
116   struct olsr_if *tmp_if;
117
118 #ifdef DEBUG
119   OLSR_PRINTF(3, "Checking for updates in the interface set\n")
120 #endif
121
122   for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
123     {
124       if(tmp_if->host_emul)
125         continue;
126       
127       if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
128         continue;
129
130       if(tmp_if->configured)
131         chk_if_changed(tmp_if);
132       else
133         chk_if_up(tmp_if, 3);
134     }
135
136   return;
137 }
138
139 /**
140  * Checks if an initialized interface is changed
141  * that is if it has been set down or the address
142  * has been changed.
143  *
144  *@param iface the olsr_if struct describing the interface
145  */
146 int
147 chk_if_changed(struct olsr_if *iface)
148 {
149   struct interface *ifp, *tmp_ifp;
150   struct ifreq ifr;
151   struct sockaddr_in6 tmp_saddr6;
152   int if_changes;
153   if_changes = 0;
154
155 #ifdef DEBUG
156   OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name)
157 #endif
158
159   if(iface->host_emul)
160     return -1;
161
162   ifp = iface->interf;
163
164   if(ifp == NULL)
165     {
166       /* Should not happen */
167       iface->configured = 0;
168       return 0;
169     }
170
171   memset(&ifr, 0, sizeof(struct ifreq));
172   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
173
174
175   /* Get flags (and check if interface exists) */
176   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
177     {
178       OLSR_PRINTF(3, "No such interface: %s\n", iface->name)
179       goto remove_interface;
180     }
181
182   ifp->int_flags = ifr.ifr_flags;
183
184   /*
185    * First check if the interface is set DOWN
186    */
187
188   if ((ifp->int_flags & IFF_UP) == 0)
189     {
190       OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name)
191       goto remove_interface;
192     }
193
194   /*
195    * We do all the interface type checks over.
196    * This is because the interface might be a PCMCIA card. Therefore
197    * It might not be the same physical interface as we configured earlier.
198    */
199
200   /* Check broadcast */
201   if ((olsr_cnf->ip_version == AF_INET) && 
202       !iface->cnf->ipv4_broadcast.v4 && /* Skip if fixed bcast */ 
203       (!(ifp->int_flags & IFF_BROADCAST))) 
204     {
205       OLSR_PRINTF(3, "\tNo broadcast - removing\n")
206       goto remove_interface;
207     }
208
209   if (ifp->int_flags & IFF_LOOPBACK)
210     {
211       OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n")
212       goto remove_interface;
213     }
214
215   ifp->is_hcif = OLSR_FALSE;
216
217   /* trying to detect if interface is wireless. */
218   ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
219
220   /* Set interface metric */
221   if(iface->cnf->weight.fixed)
222     ifp->int_metric = iface->cnf->weight.value;
223   else
224     ifp->int_metric = calculate_if_metric(ifr.ifr_name);
225
226   /* Get MTU */
227   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
228     ifp->int_mtu = 0;
229   else
230     {
231       ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
232
233       if(ifp->int_mtu != ifr.ifr_mtu)
234         {
235           ifp->int_mtu = ifr.ifr_mtu;
236           /* Create new outputbuffer */
237           net_remove_buffer(ifp); /* Remove old */
238           net_add_buffer(ifp);
239         }
240     }
241
242
243   /* Get interface index */
244   ifp->if_index = if_nametoindex(ifr.ifr_name);
245
246   /*
247    * Now check if the IP has changed
248    */
249   
250   /* IP version 6 */
251   if(olsr_cnf->ip_version == AF_INET6)
252     {
253       /* Get interface address */
254       
255       if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0)
256         {
257           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
258             OLSR_PRINTF(3, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name)
259           else
260             OLSR_PRINTF(3, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name)
261           
262           
263           goto remove_interface;
264         }
265       
266 #ifdef DEBUG
267       OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr))
268 #endif
269
270       if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0)
271         {
272           OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name)
273           OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&ifp->int6_addr.sin6_addr))
274           OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr))
275
276           /* Check main addr */
277           if(memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0)
278             {
279               /* Update main addr */
280               memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
281             }
282
283           /* Update address */
284           memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
285           memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
286
287           run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
288
289           return 1;               
290         }
291       return 0;
292
293     }
294   else
295   /* IP version 4 */
296     {
297       /* Check interface address (IPv4)*/
298       if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) 
299         {
300           OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n")
301           goto remove_interface;
302         }
303
304 #ifdef DEBUG
305       OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr_to_string(&ifr.ifr_addr))
306 #endif
307
308       if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
309                 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
310                 olsr_cnf->ipsize) != 0)
311         {
312           /* New address */
313           OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name)
314           OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr))
315           OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr))
316           
317           if(memcmp(&olsr_cnf->main_addr, 
318                     &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
319                     olsr_cnf->ipsize) == 0)
320             {
321               OLSR_PRINTF(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr))
322               olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr));
323               memcpy(&olsr_cnf->main_addr, 
324                      &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
325                      olsr_cnf->ipsize);
326             }
327
328           ifp->int_addr = ifr.ifr_addr;
329           memcpy(&ifp->ip_addr, 
330                  &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
331                  olsr_cnf->ipsize);
332
333           if_changes = 1;
334         }
335
336       /* Check netmask */
337       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
338         {
339           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
340           goto remove_interface;
341         }
342
343 #ifdef DEBUG
344       OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr_to_string(&ifr.ifr_netmask))
345 #endif
346
347       if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
348                 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, 
349                 olsr_cnf->ipsize) != 0)
350         {
351           /* New address */
352           OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name)
353           OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_netmask))
354           OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_netmask))
355
356           ifp->int_netmask = ifr.ifr_netmask;
357
358           if_changes = 1;
359         }
360       
361       if(!iface->cnf->ipv4_broadcast.v4)
362         {
363           /* Check broadcast address */      
364           if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
365             {
366               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
367               goto remove_interface;
368             }
369           
370 #ifdef DEBUG
371           OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr))
372 #endif
373           
374           if(memcmp(&((struct sockaddr_in *)&ifp->int_broadaddr)->sin_addr.s_addr,
375                     &((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr, 
376                     olsr_cnf->ipsize) != 0)
377             {
378               
379               /* New address */
380               OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name)
381               OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_broadaddr))
382               OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr))
383               
384               ifp->int_broadaddr = ifr.ifr_broadaddr;
385               if_changes = 1;
386             }            
387         }
388     }
389
390   if(if_changes)
391     run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
392
393   return if_changes;
394
395
396  remove_interface:
397   OLSR_PRINTF(1, "Removing interface %s\n", iface->name)
398   olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
399
400   /*
401    *Call possible ifchange functions registered by plugins  
402    */
403   run_ifchg_cbs(ifp, IFCHG_IF_REMOVE);
404   
405   /* Dequeue */
406   if(ifp == ifnet)
407     {
408       ifnet = ifp->int_next;
409     }
410   else
411     {
412       tmp_ifp = ifnet;
413       while(tmp_ifp->int_next != ifp)
414         {
415           tmp_ifp = tmp_ifp->int_next;
416         }
417       tmp_ifp->int_next = ifp->int_next;
418     }
419
420
421   /* Remove output buffer */
422   net_remove_buffer(ifp);
423
424   /* Check main addr */
425   if(COMP_IP(&olsr_cnf->main_addr, &ifp->ip_addr))
426     {
427       if(ifnet == NULL)
428         {
429           /* No more interfaces */
430           memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
431           OLSR_PRINTF(1, "No more interfaces...\n")
432         }
433       else
434         {
435           COPY_IP(&olsr_cnf->main_addr, &ifnet->ip_addr);
436           OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
437           olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
438         }
439     }
440
441
442   /*
443    * Deregister scheduled functions 
444    */
445
446   if (olsr_cnf->lq_level == 0)
447     {
448       olsr_remove_scheduler_event(&generate_hello, 
449                                   ifp, 
450                                   iface->cnf->hello_params.emission_interval, 
451                                   0, 
452                                   NULL);
453       olsr_remove_scheduler_event(&generate_tc, 
454                                   ifp, 
455                                   iface->cnf->tc_params.emission_interval,
456                                   0, 
457                                   NULL);
458     }
459
460   else
461     {
462       olsr_remove_scheduler_event(&olsr_output_lq_hello, 
463                                   ifp, 
464                                   iface->cnf->hello_params.emission_interval, 
465                                   0, 
466                                   NULL);
467       olsr_remove_scheduler_event(&olsr_output_lq_tc, 
468                                   ifp, 
469                                   iface->cnf->tc_params.emission_interval,
470                                   0, 
471                                   NULL);
472     }
473
474   olsr_remove_scheduler_event(&generate_mid, 
475                               ifp, 
476                               iface->cnf->mid_params.emission_interval,
477                               0, 
478                               NULL);
479   olsr_remove_scheduler_event(&generate_hna, 
480                               ifp, 
481                               iface->cnf->hna_params.emission_interval,
482                               0, 
483                               NULL);
484
485
486
487   iface->configured = 0;
488   iface->interf = NULL;
489   /* Close olsr socket */
490   close(ifp->olsr_socket);
491   remove_olsr_socket(ifp->olsr_socket, &olsr_input);
492 #ifdef USE_LIBNET
493   libnet_destroy(ifp->libnet_ctx);
494 #endif
495
496   /* Free memory */
497   free(ifp->int_name);
498   free(ifp);
499
500   if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
501     {
502       OLSR_PRINTF(1, "No more active interfaces - exiting.\n")
503       olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
504       olsr_cnf->exit_value = EXIT_FAILURE;
505       kill(getpid(), SIGINT);
506     }
507
508   return 0;
509
510 }
511
512 /**
513  * Initializes the special interface used in
514  * host-client emulation
515  */
516 int
517 add_hemu_if(struct olsr_if *iface)
518 {
519   struct interface *ifp;
520   union olsr_ip_addr null_addr;
521   olsr_u32_t addr[4];
522
523   if(!iface->host_emul)
524     return -1;
525
526   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
527
528   memset(ifp, 0, sizeof (struct interface));
529
530   iface->configured = OLSR_TRUE;
531   iface->interf = ifp;
532
533   ifp->is_hcif = OLSR_TRUE;
534   ifp->int_name = olsr_malloc(strlen("hcif01") + 1, "Interface update 3");
535   ifp->int_metric = 0;
536
537   strcpy(ifp->int_name, "hcif01");
538
539   OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name)
540
541   OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&iface->hemu_ip));
542
543   OLSR_PRINTF(1, "       Index:%d\n", iface->index);
544
545   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
546
547   ifp->int_next = ifnet;
548   ifnet = ifp;
549
550   memset(&null_addr, 0, olsr_cnf->ipsize);
551   if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
552     {
553       COPY_IP(&olsr_cnf->main_addr, &iface->hemu_ip);
554       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
555         olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
556     }
557
558   /* setting the interfaces number*/
559   ifp->if_nr = iface->index;
560
561   ifp->int_mtu = OLSR_DEFAULT_MTU;
562
563   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
564
565   /* Set up buffer */
566   net_add_buffer(ifp);
567
568
569   if(olsr_cnf->ip_version == AF_INET)
570     {
571       struct sockaddr_in sin;
572
573       memset(&sin, 0, sizeof(sin));
574
575       sin.sin_family = AF_INET;
576       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
577       sin.sin_port = htons(10150);
578  
579      /* IP version 4 */
580       ifp->ip_addr.v4 = iface->hemu_ip.v4;
581
582       memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
583       
584       /*
585        *We create one socket for each interface and bind
586        *the socket to it. This to ensure that we can control
587        *on what interface the message is transmitted
588        */
589       
590       ifp->olsr_socket = gethemusocket(&sin);
591       
592       if (ifp->olsr_socket < 0)
593         {
594           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
595           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
596           olsr_cnf->exit_value = EXIT_FAILURE;
597           kill(getpid(), SIGINT);
598         }
599
600     }
601   else
602     {
603       /* IP version 6 */
604       memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
605
606 #if 0      
607       /*
608        *We create one socket for each interface and bind
609        *the socket to it. This to ensure that we can control
610        *on what interface the message is transmitted
611        */
612       
613       ifp->olsr_socket = gethcsocket6(&addrsock6, bufspace, ifp->int_name);
614       
615       join_mcast(ifp, ifp->olsr_socket);
616       
617       if (ifp->olsr_socket < 0)
618         {
619           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
620           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
621           olsr_cnf->exit_value = EXIT_FAILURE;
622           kill(getpid(), SIGINT);
623         }
624       
625 #endif
626     }
627
628   /* Send IP as first 4/16 bytes on socket */
629   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
630   addr[0] = htonl(addr[0]);
631   addr[1] = htonl(addr[1]);
632   addr[2] = htonl(addr[2]);
633   addr[3] = htonl(addr[3]);
634
635   if(send(ifp->olsr_socket, addr , olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
636     {
637       fprintf(stderr, "Error sending IP!");
638     }  
639   
640   /* Register socket */
641   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
642
643
644   if (olsr_cnf->lq_level == 0)
645     {
646       olsr_register_scheduler_event(&generate_hello, 
647                                     ifp, 
648                                     iface->cnf->hello_params.emission_interval, 
649                                     0, 
650                                     NULL);
651       olsr_register_scheduler_event(&generate_tc, 
652                                     ifp, 
653                                     iface->cnf->tc_params.emission_interval,
654                                     0, 
655                                     NULL);
656     }
657
658   else
659     {
660       olsr_register_scheduler_event(&olsr_output_lq_hello, 
661                                     ifp, 
662                                     iface->cnf->hello_params.emission_interval, 
663                                     0, 
664                                     NULL);
665       olsr_register_scheduler_event(&olsr_output_lq_tc, 
666                                     ifp, 
667                                     iface->cnf->tc_params.emission_interval,
668                                     0, 
669                                     NULL);
670     }
671
672   olsr_register_scheduler_event(&generate_mid, 
673                                 ifp, 
674                                 iface->cnf->mid_params.emission_interval,
675                                 0, 
676                                 NULL);
677   olsr_register_scheduler_event(&generate_hna, 
678                                 ifp, 
679                                 iface->cnf->hna_params.emission_interval,
680                                 0, 
681                                 NULL);
682
683   /* Recalculate max jitter */
684
685   if((olsr_cnf->max_jitter == 0) || 
686      ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
687     olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
688
689   /* Recalculate max topology hold time */
690   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
691     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
692
693   ifp->hello_etime = iface->cnf->hello_params.emission_interval;
694   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
695   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
696   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
697   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
698
699   return 1;
700 }
701
702 /**
703  * Initializes a interface described by iface,
704  * if it is set up and is of the correct type.
705  *
706  *@param iface the olsr_if struct describing the interface
707  *@param so the socket to use for ioctls
708  *
709  */
710 int
711 chk_if_up(struct olsr_if *iface, int debuglvl)
712 {
713   struct interface ifs, *ifp;
714   struct ifreq ifr;
715   union olsr_ip_addr null_addr;
716 #ifdef linux
717   int precedence = IPTOS_PREC(olsr_cnf->tos);
718   int tos_bits = IPTOS_TOS(olsr_cnf->tos);
719 #endif
720
721   if(iface->host_emul)
722     return -1;
723
724   memset(&ifr, 0, sizeof(struct ifreq));
725   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
726
727   OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name)
728
729   /* Get flags (and check if interface exists) */
730   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
731     {
732       OLSR_PRINTF(debuglvl, "\tNo such interface!\n")
733       return 0;
734     }
735
736   ifs.int_flags = ifr.ifr_flags;      
737
738
739   if ((ifs.int_flags & IFF_UP) == 0)
740     {
741       OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n")
742       return 0;
743     }
744
745   /* Check broadcast */
746   if ((olsr_cnf->ip_version == AF_INET) &&
747       !iface->cnf->ipv4_broadcast.v4 && /* Skip if fixed bcast */ 
748       (!(ifs.int_flags & IFF_BROADCAST))) 
749     {
750       OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n")
751       return 0;
752     }
753
754
755   if (ifs.int_flags & IFF_LOOPBACK)
756     {
757       OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n")
758       return 0;
759     }
760
761   ifs.is_hcif = OLSR_FALSE;
762
763   /* trying to detect if interface is wireless. */
764   ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
765
766   if(ifs.is_wireless)
767     OLSR_PRINTF(debuglvl, "\tWireless interface detected\n")
768   else
769     OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n")
770
771   
772   /* IP version 6 */
773   if(olsr_cnf->ip_version == AF_INET6)
774     {
775       /* Get interface address */
776       
777       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
778         {
779           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
780             OLSR_PRINTF(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name)
781           else
782             OLSR_PRINTF(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name)
783           
784           return 0;
785         }
786       
787       OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr))
788       
789       /* Multicast */
790       ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) ? 
791         iface->cnf->ipv6_multi_site.v6 :
792         iface->cnf->ipv6_multi_glbl.v6;
793       /* Set address family */
794       ifs.int6_multaddr.sin6_family = AF_INET6;
795       /* Set port */
796       ifs.int6_multaddr.sin6_port = htons(OLSRPORT);
797       
798       OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr))
799       
800     }
801   /* IP version 4 */
802   else
803     {
804       /* Get interface address (IPv4)*/
805       if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) 
806         {
807           OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n")
808           return 0;
809         }
810       
811       ifs.int_addr = ifr.ifr_addr;
812       
813       /* Find netmask */
814       
815       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
816         {
817           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
818           return 0;
819         }
820       
821       ifs.int_netmask = ifr.ifr_netmask;
822       
823       /* Find broadcast address */
824       if(iface->cnf->ipv4_broadcast.v4)
825         {
826           /* Specified broadcast */
827           memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
828           memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, 
829                  &iface->cnf->ipv4_broadcast.v4, 
830                  sizeof(olsr_u32_t));
831         }
832       else
833         {
834           /* Autodetect */
835           if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
836             {
837               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
838               return 0;
839             }
840           
841           ifs.int_broadaddr = ifr.ifr_broadaddr;
842         }
843       
844       /* Deactivate IP spoof filter */
845       deactivate_spoof(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
846       
847       /* Disable ICMP redirects */
848       disable_redirects(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
849       
850     }
851   
852   
853   /* Get interface index */
854   
855   ifs.if_index = if_nametoindex(ifr.ifr_name);
856   
857   /* Set interface metric */
858   /* Set interface metric */
859   if(iface->cnf->weight.fixed)
860     ifs.int_metric = iface->cnf->weight.value;
861   else
862     ifs.int_metric = calculate_if_metric(ifr.ifr_name);
863   OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric)
864
865   /* setting the interfaces number*/
866   ifs.if_nr = iface->index;
867
868
869   /* Get MTU */
870   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
871     ifs.int_mtu = OLSR_DEFAULT_MTU;
872   else
873     ifs.int_mtu = ifr.ifr_mtu;
874
875   ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
876
877   /* Set up buffer */
878   net_add_buffer(&ifs);
879                
880   OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu)
881
882   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
883   OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_nr)
884
885   if(olsr_cnf->ip_version == AF_INET)
886     {
887       OLSR_PRINTF(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr))
888       OLSR_PRINTF(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask))
889       OLSR_PRINTF(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr))
890     }
891   else
892     {
893       OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr))
894       OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr))
895     }
896   
897   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
898
899   iface->configured = 1;
900   iface->interf = ifp;
901   
902   memcpy(ifp, &ifs, sizeof(struct interface));
903   
904   ifp->libnet_ctx = NULL;  
905   ifp->gen_properties = NULL;
906   ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
907       
908   strcpy(ifp->int_name, ifr.ifr_name);
909   /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
910   ifp->int_next = ifnet;
911   ifnet = ifp;
912
913   if(olsr_cnf->ip_version == AF_INET)
914     {
915       /* IP version 4 */
916       ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
917       /*
918        *We create one socket for each interface and bind
919        *the socket to it. This to ensure that we can control
920        *on what interface the message is transmitted
921        */
922       
923       ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
924       
925       if (ifp->olsr_socket < 0)
926         {
927           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
928           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
929           olsr_cnf->exit_value = EXIT_FAILURE;
930           kill(getpid(), SIGINT);
931         }
932
933     }
934   else
935     {
936       /* IP version 6 */
937       memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize);
938
939       
940       /*
941        *We create one socket for each interface and bind
942        *the socket to it. This to ensure that we can control
943        *on what interface the message is transmitted
944        */
945       
946       ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
947       
948       join_mcast(ifp, ifp->olsr_socket);
949       
950       if (ifp->olsr_socket < 0)
951         {
952           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
953           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
954           olsr_cnf->exit_value = EXIT_FAILURE;
955           kill(getpid(), SIGINT);
956         }
957       
958     }
959
960 #ifdef USE_LIBNET
961 #if 1
962   ifp->libnet_ctx = libnet_init((olsr_cnf->ip_version == AF_INET) ? 
963                                 LIBNET_RAW4 : LIBNET_RAW6, 
964                                 ifp->int_name, get_libnet_errbuf());
965 #else
966   ifp->libnet_ctx = libnet_init(LIBNET_LINK, ifp->int_name, get_libnet_errbuf());
967 #endif
968
969   if(ifp->libnet_ctx == NULL)
970     {
971       fprintf(stderr, "Could not initialize libnet... exiting!\n\n");
972       olsr_syslog(OLSR_LOG_ERR, "Could not initialize libnet... exiting!\n\n");
973       olsr_cnf->exit_value = EXIT_FAILURE;
974       kill(getpid(), SIGINT);
975     }
976 #endif
977   set_buffer_timer(ifp);
978
979   /* Register socket */
980   add_olsr_socket(ifp->olsr_socket, &olsr_input);
981   
982 #ifdef linux 
983   /* Set TOS */
984   
985   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
986     {
987       perror("setsockopt(SO_PRIORITY)");
988       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
989     }
990   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
991     {
992       perror("setsockopt(IP_TOS)");
993       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
994     }
995 #endif
996   
997   /*
998    *Initialize sequencenumber as a random 16bit value
999    */
1000   ifp->olsr_seqnum = random() & 0xFFFF;
1001
1002   /*
1003    * Set main address if this is the only interface
1004    */
1005   memset(&null_addr, 0, olsr_cnf->ipsize);
1006   if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
1007     {
1008       COPY_IP(&olsr_cnf->main_addr, &ifp->ip_addr);
1009       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
1010       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
1011     }
1012   
1013   /*
1014    * Register scheduled functions 
1015    */
1016
1017   if (olsr_cnf->lq_level == 0)
1018     {
1019       olsr_register_scheduler_event(&generate_hello, 
1020                                     ifp, 
1021                                     iface->cnf->hello_params.emission_interval, 
1022                                     0, 
1023                                     NULL);
1024       olsr_register_scheduler_event(&generate_tc, 
1025                                     ifp, 
1026                                     iface->cnf->tc_params.emission_interval,
1027                                     0, 
1028                                     NULL);
1029     }
1030
1031   else
1032     {
1033       olsr_register_scheduler_event(&olsr_output_lq_hello, 
1034                                     ifp, 
1035                                     iface->cnf->hello_params.emission_interval, 
1036                                     0, 
1037                                     NULL);
1038       olsr_register_scheduler_event(&olsr_output_lq_tc, 
1039                                     ifp, 
1040                                     iface->cnf->tc_params.emission_interval,
1041                                     0, 
1042                                     NULL);
1043     }
1044
1045   olsr_register_scheduler_event(&generate_mid, 
1046                                 ifp, 
1047                                 iface->cnf->mid_params.emission_interval,
1048                                 0, 
1049                                 NULL);
1050   olsr_register_scheduler_event(&generate_hna, 
1051                                 ifp, 
1052                                 iface->cnf->hna_params.emission_interval,
1053                                 0, 
1054                                 NULL);
1055
1056   /* Recalculate max jitter */
1057
1058   if((olsr_cnf->max_jitter == 0) || 
1059      ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
1060     olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
1061
1062   /* Recalculate max topology hold time */
1063   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
1064     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
1065
1066   ifp->hello_etime = iface->cnf->hello_params.emission_interval;
1067   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
1068   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
1069   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
1070   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
1071
1072
1073   /*
1074    *Call possible ifchange functions registered by plugins  
1075    */
1076   run_ifchg_cbs(ifp, IFCHG_IF_ADD);
1077
1078   return 1;
1079 }
1080
1081