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