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