* OLSR_PRINTF() is now a real C expression
[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.48 2007/04/25 22:08:18 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, "       Index:%d\n", iface->index);
554
555   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
556
557   ifp->int_next = ifnet;
558   ifnet = ifp;
559
560   memset(&null_addr, 0, olsr_cnf->ipsize);
561   if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
562     {
563       COPY_IP(&olsr_cnf->main_addr, &iface->hemu_ip);
564       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
565         olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
566     }
567
568   /* setting the interfaces number*/
569   ifp->if_nr = iface->index;
570
571   ifp->int_mtu = OLSR_DEFAULT_MTU;
572
573   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
574
575   /* Set up buffer */
576   net_add_buffer(ifp);
577
578
579   if(olsr_cnf->ip_version == AF_INET)
580     {
581       struct sockaddr_in sin;
582
583       memset(&sin, 0, sizeof(sin));
584
585       sin.sin_family = AF_INET;
586       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
587       sin.sin_port = htons(10150);
588  
589      /* IP version 4 */
590       ifp->ip_addr.v4 = iface->hemu_ip.v4;
591
592       memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
593       
594       /*
595        *We create one socket for each interface and bind
596        *the socket to it. This to ensure that we can control
597        *on what interface the message is transmitted
598        */
599       
600       ifp->olsr_socket = gethemusocket(&sin);
601       
602       if (ifp->olsr_socket < 0)
603         {
604           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
605           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
606           olsr_cnf->exit_value = EXIT_FAILURE;
607           kill(getpid(), SIGINT);
608         }
609
610     }
611   else
612     {
613       /* IP version 6 */
614       memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
615
616 #if 0      
617       /*
618        *We create one socket for each interface and bind
619        *the socket to it. This to ensure that we can control
620        *on what interface the message is transmitted
621        */
622       
623       ifp->olsr_socket = gethcsocket6(&addrsock6, bufspace, ifp->int_name);
624       
625       join_mcast(ifp, ifp->olsr_socket);
626       
627       if (ifp->olsr_socket < 0)
628         {
629           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
630           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
631           olsr_cnf->exit_value = EXIT_FAILURE;
632           kill(getpid(), SIGINT);
633         }
634       
635 #endif
636     }
637
638   /* Send IP as first 4/16 bytes on socket */
639   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
640   addr[0] = htonl(addr[0]);
641   addr[1] = htonl(addr[1]);
642   addr[2] = htonl(addr[2]);
643   addr[3] = htonl(addr[3]);
644
645   if(send(ifp->olsr_socket, addr , olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
646     {
647       fprintf(stderr, "Error sending IP!");
648     }  
649   
650   /* Register socket */
651   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
652
653
654   if (olsr_cnf->lq_level == 0)
655     {
656       olsr_register_scheduler_event(&generate_hello, 
657                                     ifp, 
658                                     iface->cnf->hello_params.emission_interval, 
659                                     0, 
660                                     NULL);
661       olsr_register_scheduler_event(&generate_tc, 
662                                     ifp, 
663                                     iface->cnf->tc_params.emission_interval,
664                                     0, 
665                                     NULL);
666     }
667
668   else
669     {
670       olsr_register_scheduler_event(&olsr_output_lq_hello, 
671                                     ifp, 
672                                     iface->cnf->hello_params.emission_interval, 
673                                     0, 
674                                     NULL);
675       olsr_register_scheduler_event(&olsr_output_lq_tc, 
676                                     ifp, 
677                                     iface->cnf->tc_params.emission_interval,
678                                     0, 
679                                     NULL);
680     }
681
682   olsr_register_scheduler_event(&generate_mid, 
683                                 ifp, 
684                                 iface->cnf->mid_params.emission_interval,
685                                 0, 
686                                 NULL);
687   olsr_register_scheduler_event(&generate_hna, 
688                                 ifp, 
689                                 iface->cnf->hna_params.emission_interval,
690                                 0, 
691                                 NULL);
692
693   /* Recalculate max jitter */
694
695   if((olsr_cnf->max_jitter == 0) || 
696      ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
697     olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
698
699   /* Recalculate max topology hold time */
700   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
701     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
702
703   ifp->hello_etime = iface->cnf->hello_params.emission_interval;
704   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
705   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
706   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
707   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
708
709   return 1;
710 }
711
712 static char basename[32];
713 char* if_basename(char* name);
714 char* if_basename(char* name)
715 {
716         char *p = strchr(name, ':');
717         if (0 == p || p - name >= (int)(sizeof(basename) / sizeof(basename[0]) - 1)) return name;
718         memcpy(basename, name, p - name);
719         basename[p - name] = 0;
720         return basename;
721 }
722
723 /**
724  * Initializes a interface described by iface,
725  * if it is set up and is of the correct type.
726  *
727  *@param iface the olsr_if struct describing the interface
728  *@param so the socket to use for ioctls
729  *
730  */
731 int
732 chk_if_up(struct olsr_if *iface, int debuglvl)
733 {
734   struct interface ifs, *ifp;
735   struct ifreq ifr;
736   union olsr_ip_addr null_addr;
737 #ifdef linux
738   int precedence = IPTOS_PREC(olsr_cnf->tos);
739   int tos_bits = IPTOS_TOS(olsr_cnf->tos);
740 #endif
741
742   if(iface->host_emul)
743     return -1;
744
745   memset(&ifr, 0, sizeof(struct ifreq));
746   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
747
748   OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
749
750   /* Get flags (and check if interface exists) */
751   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
752     {
753       OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
754       return 0;
755     }
756
757   memset(&ifs.netbuf, 0, sizeof(struct olsr_netbuf));
758   ifs.int_flags = ifr.ifr_flags;      
759
760
761   if ((ifs.int_flags & IFF_UP) == 0)
762     {
763       OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n");
764       return 0;
765     }
766
767   /* Check broadcast */
768   if ((olsr_cnf->ip_version == AF_INET) &&
769       !iface->cnf->ipv4_broadcast.v4 && /* Skip if fixed bcast */ 
770       (!(ifs.int_flags & IFF_BROADCAST))) 
771     {
772       OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
773       return 0;
774     }
775
776
777   if (ifs.int_flags & IFF_LOOPBACK)
778     {
779       OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
780       return 0;
781     }
782
783   ifs.is_hcif = OLSR_FALSE;
784
785   /* trying to detect if interface is wireless. */
786   ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
787
788   if(ifs.is_wireless)
789     OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
790   else
791     OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
792
793   
794   /* IP version 6 */
795   if(olsr_cnf->ip_version == AF_INET6)
796     {
797       /* Get interface address */
798       
799       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
800         {
801           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
802             OLSR_PRINTF(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
803           else
804             OLSR_PRINTF(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
805           
806           return 0;
807         }
808       
809       OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
810       
811       /* Multicast */
812       ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) ? 
813         iface->cnf->ipv6_multi_site.v6 :
814         iface->cnf->ipv6_multi_glbl.v6;
815       /* Set address family */
816       ifs.int6_multaddr.sin6_family = AF_INET6;
817       /* Set port */
818       ifs.int6_multaddr.sin6_port = htons(OLSRPORT);
819       
820 #ifdef __MacOSX__
821       ifs.int6_multaddr.sin6_scope_id = 0;
822 #endif
823
824       OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
825       
826     }
827   /* IP version 4 */
828   else
829     {
830       /* Get interface address (IPv4)*/
831       if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) 
832         {
833           OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
834           return 0;
835         }
836       
837       ifs.int_addr = ifr.ifr_addr;
838       
839       /* Find netmask */
840       
841       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
842         {
843           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
844           return 0;
845         }
846       
847       ifs.int_netmask = ifr.ifr_netmask;
848       
849       /* Find broadcast address */
850       if(iface->cnf->ipv4_broadcast.v4)
851         {
852           /* Specified broadcast */
853           memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
854           memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, 
855                  &iface->cnf->ipv4_broadcast.v4, 
856                  sizeof(olsr_u32_t));
857         }
858       else
859         {
860           /* Autodetect */
861           if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
862             {
863               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
864               return 0;
865             }
866           
867           ifs.int_broadaddr = ifr.ifr_broadaddr;
868         }
869       
870       /* Deactivate IP spoof filter */
871       deactivate_spoof(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
872       
873       /* Disable ICMP redirects */
874       disable_redirects(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
875       
876     }
877   
878   
879   /* Get interface index */
880   
881   ifs.if_index = if_nametoindex(ifr.ifr_name);
882   
883   /* Set interface metric */
884   if(iface->cnf->weight.fixed)
885     ifs.int_metric = iface->cnf->weight.value;
886   else
887     ifs.int_metric = calculate_if_metric(ifr.ifr_name);
888   OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
889
890   /* setting the interfaces number*/
891   ifs.if_nr = iface->index;
892
893
894   /* Get MTU */
895   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
896     ifs.int_mtu = OLSR_DEFAULT_MTU;
897   else
898     ifs.int_mtu = ifr.ifr_mtu;
899
900   ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
901
902   ifs.ttl_index = 0;
903
904   /* Set up buffer */
905   net_add_buffer(&ifs);
906                
907   OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
908
909   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
910   OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_nr);
911
912   if(olsr_cnf->ip_version == AF_INET)
913     {
914       OLSR_PRINTF(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr));
915       OLSR_PRINTF(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask));
916       OLSR_PRINTF(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr));
917     }
918   else
919     {
920       OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
921       OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
922     }
923   
924   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
925
926   iface->configured = 1;
927   iface->interf = ifp;
928   
929   memcpy(ifp, &ifs, sizeof(struct interface));
930   
931   ifp->gen_properties = NULL;
932   ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
933       
934   strcpy(ifp->int_name, if_basename(ifr.ifr_name));
935   /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
936   ifp->int_next = ifnet;
937   ifnet = ifp;
938
939   if(olsr_cnf->ip_version == AF_INET)
940     {
941       /* IP version 4 */
942       ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
943       /*
944        *We create one socket for each interface and bind
945        *the socket to it. This to ensure that we can control
946        *on what interface the message is transmitted
947        */
948       
949       ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
950       
951       if (ifp->olsr_socket < 0)
952         {
953           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
954           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
955           olsr_cnf->exit_value = EXIT_FAILURE;
956           kill(getpid(), SIGINT);
957         }
958
959     }
960   else
961     {
962       /* IP version 6 */
963       memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize);
964
965       
966       /*
967        *We create one socket for each interface and bind
968        *the socket to it. This to ensure that we can control
969        *on what interface the message is transmitted
970        */
971       
972       ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
973       
974       join_mcast(ifp, ifp->olsr_socket);
975       
976       if (ifp->olsr_socket < 0)
977         {
978           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
979           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
980           olsr_cnf->exit_value = EXIT_FAILURE;
981           kill(getpid(), SIGINT);
982         }
983       
984     }
985
986   set_buffer_timer(ifp);
987
988   /* Register socket */
989   add_olsr_socket(ifp->olsr_socket, &olsr_input);
990   
991 #ifdef linux 
992   /* Set TOS */
993   
994   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
995     {
996       perror("setsockopt(SO_PRIORITY)");
997       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
998     }
999   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
1000     {
1001       perror("setsockopt(IP_TOS)");
1002       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
1003     }
1004 #endif
1005   
1006   /*
1007    *Initialize sequencenumber as a random 16bit value
1008    */
1009   ifp->olsr_seqnum = random() & 0xFFFF;
1010
1011   /*
1012    * Set main address if this is the only interface
1013    */
1014   memset(&null_addr, 0, olsr_cnf->ipsize);
1015   if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
1016     {
1017       COPY_IP(&olsr_cnf->main_addr, &ifp->ip_addr);
1018       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
1019       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));
1020     }
1021   
1022   /*
1023    * Register scheduled functions 
1024    */
1025
1026   if (olsr_cnf->lq_level == 0)
1027     {
1028       olsr_register_scheduler_event(&generate_hello, 
1029                                     ifp, 
1030                                     iface->cnf->hello_params.emission_interval, 
1031                                     0, 
1032                                     NULL);
1033       olsr_register_scheduler_event(&generate_tc, 
1034                                     ifp, 
1035                                     iface->cnf->tc_params.emission_interval,
1036                                     0, 
1037                                     NULL);
1038     }
1039
1040   else
1041     {
1042       olsr_register_scheduler_event(&olsr_output_lq_hello, 
1043                                     ifp, 
1044                                     iface->cnf->hello_params.emission_interval, 
1045                                     0, 
1046                                     NULL);
1047       olsr_register_scheduler_event(&olsr_output_lq_tc, 
1048                                     ifp, 
1049                                     iface->cnf->tc_params.emission_interval,
1050                                     0, 
1051                                     NULL);
1052     }
1053
1054   olsr_register_scheduler_event(&generate_mid, 
1055                                 ifp, 
1056                                 iface->cnf->mid_params.emission_interval,
1057                                 0, 
1058                                 NULL);
1059   olsr_register_scheduler_event(&generate_hna, 
1060                                 ifp, 
1061                                 iface->cnf->hna_params.emission_interval,
1062                                 0, 
1063                                 NULL);
1064
1065   /* Recalculate max jitter */
1066
1067   if((olsr_cnf->max_jitter == 0) || 
1068      ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
1069     olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
1070
1071   /* Recalculate max topology hold time */
1072   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
1073     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
1074
1075   ifp->hello_etime = iface->cnf->hello_params.emission_interval;
1076   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
1077   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
1078   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
1079   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
1080
1081
1082   /*
1083    *Call possible ifchange functions registered by plugins  
1084    */
1085   run_ifchg_cbs(ifp, IFCHG_IF_ADD);
1086
1087   return 1;
1088 }
1089
1090