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