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