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