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