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