Removed USE_LINK_QUALITY #ifdefs. The link quality code is now always
[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.9 2004/12/04 17:06:57 tlopatic 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__
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) && (!(ifp->int_flags & IFF_BROADCAST))) 
201     {
202       olsr_printf(3, "\tNo broadcast - removing\n");
203       goto remove_interface;
204     }
205
206   if (ifp->int_flags & IFF_LOOPBACK)
207     {
208       olsr_printf(3, "\tThis is a loopback interface - removing it...\n");
209       goto remove_interface;
210     }
211
212
213   /* trying to detect if interface is wireless. */
214   ifp->is_wireless = check_wireless_interface(&ifr);
215
216   /* Set interface metric */
217   ifp->int_metric = ifp->is_wireless;
218
219   /* Get MTU */
220   if (ioctl(ioctl_s, SIOCGIFMTU, &ifr) < 0)
221     ifp->int_mtu = 0;
222   else
223     {
224       if(ifp->int_mtu != ifr.ifr_mtu)
225         {
226           ifp->int_mtu = ifr.ifr_mtu;
227           /* Create new outputbuffer */
228           net_remove_buffer(ifp); /* Remove old */
229           net_add_buffer(ifp);
230         }
231     }
232
233
234   /* Get interface index */
235   ifp->if_index = if_nametoindex(ifr.ifr_name);
236
237   /*
238    * Now check if the IP has changed
239    */
240   
241   /* IP version 6 */
242   if(olsr_cnf->ip_version == AF_INET6)
243     {
244       /* Get interface address */
245       
246       if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0)
247         {
248           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
249             olsr_printf(3, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
250           else
251             olsr_printf(3, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
252           
253           
254           goto remove_interface;
255         }
256       
257 #ifdef DEBUG
258       olsr_printf(3, "\tAddress: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr));
259 #endif
260
261       if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, ipsize) != 0)
262         {
263           olsr_printf(1, "New IP address for %s:\n", ifr.ifr_name);
264           olsr_printf(1, "\tOld: %s\n", ip6_to_string(&ifp->int6_addr.sin6_addr));
265           olsr_printf(1, "\tNew: %s\n", ip6_to_string(&tmp_saddr6.sin6_addr));
266
267           /* Check main addr */
268           if(memcmp(&main_addr, &tmp_saddr6.sin6_addr, ipsize) == 0)
269             {
270               /* Update main addr */
271               memcpy(&main_addr, &tmp_saddr6.sin6_addr, ipsize);
272             }
273
274           /* Update address */
275           memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, ipsize);
276           memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, ipsize);
277
278           /*
279            *Call possible ifchange functions registered by plugins  
280            */
281           tmp_ifchgf_list = ifchgf_list;
282           while(tmp_ifchgf_list != NULL)
283             {
284               tmp_ifchgf_list->function(ifp, IFCHG_IF_UPDATE);
285               tmp_ifchgf_list = tmp_ifchgf_list->next;
286             }
287
288           return 1;               
289         }
290       return 0;
291
292     }
293   else
294   /* IP version 4 */
295     {
296       /* Check interface address (IPv4)*/
297       if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0) 
298         {
299           olsr_printf(1, "\tCould not get address of interface - removing it\n");
300           goto remove_interface;
301         }
302
303 #ifdef DEBUG
304       olsr_printf(3, "\tAddress:%s\n", sockaddr_to_string(&ifr.ifr_addr));
305 #endif
306
307       if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
308                 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
309                 ipsize) != 0)
310         {
311           /* New address */
312           olsr_printf(1, "IPv4 address changed for %s\n", ifr.ifr_name);
313           olsr_printf(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr));
314           olsr_printf(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr));
315           
316           if(memcmp(&main_addr, 
317                     &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
318                     ipsize) == 0)
319             {
320               olsr_printf(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr));
321               olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr));
322               memcpy(&main_addr, 
323                      &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
324                      ipsize);
325             }
326
327           ifp->int_addr = ifr.ifr_addr;
328           memcpy(&ifp->ip_addr, 
329                  &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
330                  ipsize);
331
332           if_changes = 1;
333         }
334
335       /* Check netmask */
336       if (ioctl(ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
337         {
338           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
339           goto remove_interface;
340         }
341
342 #ifdef DEBUG
343       olsr_printf(3, "\tNetmask:%s\n", sockaddr_to_string(&ifr.ifr_netmask));
344 #endif
345
346       if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
347                 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, 
348                 ipsize) != 0)
349         {
350           /* New address */
351           olsr_printf(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
352           olsr_printf(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_netmask));
353           olsr_printf(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_netmask));
354
355           ifp->int_netmask = ifr.ifr_netmask;
356
357           if_changes = 1;
358         }
359       
360       if(!iface->cnf->ipv4_broadcast.v4)
361         {
362           /* Check broadcast address */      
363           if (ioctl(ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
364             {
365               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
366               goto remove_interface;
367             }
368           
369 #ifdef DEBUG
370           olsr_printf(3, "\tBroadcast address:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr));
371 #endif
372           
373           if(memcmp(&((struct sockaddr_in *)&ifp->int_broadaddr)->sin_addr.s_addr,
374                     &((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr, 
375                     ipsize) != 0)
376             {
377               
378               /* New address */
379               olsr_printf(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
380               olsr_printf(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_broadaddr));
381               olsr_printf(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_broadaddr));
382               
383               ifp->int_broadaddr = ifr.ifr_broadaddr;
384               if_changes = 1;
385             }            
386         }
387     }
388
389   if(if_changes)
390     {
391       /*
392        *Call possible ifchange functions registered by plugins  
393        */
394       tmp_ifchgf_list = ifchgf_list;
395       while(tmp_ifchgf_list != NULL)
396         {
397           tmp_ifchgf_list->function(ifp, IFCHG_IF_UPDATE);
398           tmp_ifchgf_list = tmp_ifchgf_list->next;
399         }
400     }
401   return if_changes;
402
403
404  remove_interface:
405   olsr_printf(1, "Removing interface %s\n", iface->name);
406   olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
407
408   /*
409    *Call possible ifchange functions registered by plugins  
410    */
411   tmp_ifchgf_list = ifchgf_list;
412   while(tmp_ifchgf_list != NULL)
413     {
414       tmp_ifchgf_list->function(ifp, IFCHG_IF_REMOVE);
415       tmp_ifchgf_list = tmp_ifchgf_list->next;
416     }
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(&main_addr, &ifp->ip_addr))
439     {
440       if(ifnet == NULL)
441         {
442           /* No more interfaces */
443           memset(&main_addr, 0, ipsize);
444           olsr_printf(1, "No more interfaces...\n");
445         }
446       else
447         {
448           COPY_IP(&main_addr, &ifnet->ip_addr);
449           olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
450           olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&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   /* Free memory */
506   free(ifp->int_name);
507   free(ifp);
508
509   if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
510     {
511       olsr_printf(1, "No more active interfaces - exiting.\n");
512       olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
513       exit_value = EXIT_FAILURE;
514       kill(getpid(), SIGINT);
515     }
516
517   return 0;
518
519 }
520
521
522
523 /**
524  * Initializes a interface described by iface,
525  * if it is set up and is of the correct type.
526  *
527  *@param iface the olsr_if struct describing the interface
528  *@param so the socket to use for ioctls
529  *
530  */
531 int
532 chk_if_up(struct olsr_if *iface, int debuglvl)
533 {
534   struct interface ifs, *ifp;
535   struct ifreq ifr;
536   union olsr_ip_addr null_addr;
537   struct ifchgf *tmp_ifchgf_list;
538 #ifdef linux
539   int precedence = IPTOS_PREC(olsr_cnf->tos);
540   int tos_bits = IPTOS_TOS(olsr_cnf->tos);
541 #endif
542
543   memset(&ifr, 0, sizeof(struct ifreq));
544   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
545
546   olsr_printf(debuglvl, "Checking %s:\n", ifr.ifr_name);
547
548   /* Get flags (and check if interface exists) */
549   if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
550     {
551       olsr_printf(debuglvl, "\tNo such interface!\n");
552       return 0;
553     }
554
555   ifs.int_flags = ifr.ifr_flags | IFF_INTERFACE;      
556
557
558   if ((ifs.int_flags & IFF_UP) == 0)
559     {
560       olsr_printf(debuglvl, "\tInterface not up - skipping it...\n");
561       return 0;
562     }
563
564   /* Check broadcast */
565   if ((olsr_cnf->ip_version == AF_INET) && (!(ifs.int_flags & IFF_BROADCAST))) 
566     {
567       olsr_printf(debuglvl, "\tNo broadcast - skipping\n");
568       return 0;
569     }
570
571
572   if (ifs.int_flags & IFF_LOOPBACK)
573     {
574       olsr_printf(debuglvl, "\tThis is a loopback interface - skipping it...\n");
575       return 0;
576     }
577
578   /* trying to detect if interface is wireless. */
579   if(check_wireless_interface(&ifr))
580     {
581       olsr_printf(debuglvl, "\tWireless interface detected\n");
582       ifs.is_wireless = 1;
583     }
584   else
585     {
586       olsr_printf(debuglvl, "\tNot a wireless interface\n");
587       ifs.is_wireless = 0;
588     }
589
590   
591   /* IP version 6 */
592   if(olsr_cnf->ip_version == AF_INET6)
593     {
594       /* Get interface address */
595       
596       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
597         {
598           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
599             olsr_printf(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
600           else
601             olsr_printf(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
602           
603           return 0;
604         }
605       
606       olsr_printf(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
607       
608       /* Multicast */
609       ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == 1) ? iface->cnf->ipv6_multi_site.v6 :iface->cnf->ipv6_multi_site.v6;
610       /* Set address family */
611       ifs.int6_multaddr.sin6_family = AF_INET6;
612       /* Set port */
613       ifs.int6_multaddr.sin6_port = olsr_udp_port;
614       
615       olsr_printf(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
616       
617     }
618   /* IP version 4 */
619   else
620     {
621       /* Get interface address (IPv4)*/
622       if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0) 
623         {
624           olsr_printf(debuglvl, "\tCould not get address of interface - skipping it\n");
625           return 0;
626         }
627       
628       ifs.int_addr = ifr.ifr_addr;
629       
630       /* Find netmask */
631       
632       if (ioctl(ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
633         {
634           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
635           return 0;
636         }
637       
638       ifs.int_netmask = ifr.ifr_netmask;
639       
640       /* Find broadcast address */
641       if(iface->cnf->ipv4_broadcast.v4)
642         {
643           /* Specified broadcast */
644           memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
645           memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, 
646                  &iface->cnf->ipv4_broadcast.v4, 
647                  sizeof(olsr_u32_t));
648         }
649       else
650         {
651           /* Autodetect */
652           if (ioctl(ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
653             {
654               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
655               return 0;
656             }
657           
658           ifs.int_broadaddr = ifr.ifr_broadaddr;
659         }
660       
661       /* Deactivate IP spoof filter */
662       deactivate_spoof(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
663       
664       /* Disable ICMP redirects */
665       disable_redirects(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
666       
667     }
668   
669   
670   /* Get interface index */
671   
672   ifs.if_index = if_nametoindex(ifr.ifr_name);
673   
674   /* Set interface metric */
675   ifs.int_metric = ifs.is_wireless;
676   
677   /* setting the interfaces number*/
678   ifs.if_nr = iface->index;
679
680
681   /* Get MTU */
682   if (ioctl(ioctl_s, SIOCGIFMTU, &ifr) < 0)
683     ifs.int_mtu = OLSR_DEFAULT_MTU;
684   else
685     ifs.int_mtu = ifr.ifr_mtu;
686
687   /* Set up buffer */
688   net_add_buffer(&ifs);
689                
690   olsr_printf(1, "\tMTU: %d\n", ifs.int_mtu);
691
692   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
693   olsr_printf(1, "\tIndex %d\n", iface->name, ifs.if_nr);
694
695   if(olsr_cnf->ip_version == AF_INET)
696     {
697       olsr_printf(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr));
698       olsr_printf(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask));
699       olsr_printf(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr));
700     }
701   else
702     {
703       olsr_printf(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
704       olsr_printf(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
705     }
706   
707   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
708   
709   iface->configured = 1;
710   iface->interf = ifp;
711   
712   memcpy(ifp, &ifs, sizeof(struct interface));
713   
714   ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
715       
716   strcpy(ifp->int_name, ifr.ifr_name);
717   /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
718   ifp->int_next = ifnet;
719   ifnet = ifp;
720
721   if(olsr_cnf->ip_version == AF_INET)
722     {
723       /* IP version 4 */
724       ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
725       
726       /*
727        *We create one socket for each interface and bind
728        *the socket to it. This to ensure that we can control
729        *on what interface the message is transmitted
730        */
731       
732       ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
733       
734       if (ifp->olsr_socket < 0)
735         {
736           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
737           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
738           exit_value = EXIT_FAILURE;
739           kill(getpid(), SIGINT);
740         }
741     }
742   else
743     {
744       /* IP version 6 */
745       memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, ipsize);
746
747       
748       /*
749        *We create one socket for each interface and bind
750        *the socket to it. This to ensure that we can control
751        *on what interface the message is transmitted
752        */
753       
754       ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
755       
756       join_mcast(ifp, ifp->olsr_socket);
757       
758       if (ifp->olsr_socket < 0)
759         {
760           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
761           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
762           exit_value = EXIT_FAILURE;
763           kill(getpid(), SIGINT);
764         }
765       
766     }
767   
768   /* Register socket */
769   add_olsr_socket(ifp->olsr_socket, &olsr_input);
770   
771 #ifdef linux 
772   /* Set TOS */
773   
774   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
775     {
776       perror("setsockopt(SO_PRIORITY)");
777       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
778     }
779   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
780     {
781       perror("setsockopt(IP_TOS)");
782       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
783     }
784 #endif
785   
786   /*
787    *Initialize sequencenumber as a random 16bit value
788    */
789   ifp->olsr_seqnum = random() & 0xFFFF;
790
791   /*
792    * Set main address if this is the only interface
793    */
794   memset(&null_addr, 0, ipsize);
795   if(COMP_IP(&null_addr, &main_addr))
796     {
797       COPY_IP(&main_addr, &ifp->ip_addr);
798       olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
799       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&main_addr));
800     }
801   
802   /*
803    * Register scheduled functions 
804    */
805
806   if (olsr_cnf->lq_level == 0)
807     {
808       olsr_register_scheduler_event(&generate_hello, 
809                                     ifp, 
810                                     iface->cnf->hello_params.emission_interval, 
811                                     0, 
812                                     NULL);
813       olsr_register_scheduler_event(&generate_tc, 
814                                     ifp, 
815                                     iface->cnf->tc_params.emission_interval,
816                                     0, 
817                                     NULL);
818     }
819
820   else
821     {
822       olsr_register_scheduler_event(&olsr_output_lq_hello, 
823                                     ifp, 
824                                     iface->cnf->hello_params.emission_interval, 
825                                     0, 
826                                     NULL);
827       olsr_register_scheduler_event(&olsr_output_lq_tc, 
828                                     ifp, 
829                                     iface->cnf->tc_params.emission_interval,
830                                     0, 
831                                     NULL);
832     }
833
834   olsr_register_scheduler_event(&generate_mid, 
835                                 ifp, 
836                                 iface->cnf->mid_params.emission_interval,
837                                 0, 
838                                 NULL);
839   olsr_register_scheduler_event(&generate_hna, 
840                                 ifp, 
841                                 iface->cnf->hna_params.emission_interval,
842                                 0, 
843                                 NULL);
844
845   /* Recalculate max jitter */
846
847   if((max_jitter == 0) || ((iface->cnf->hello_params.emission_interval / 4) < max_jitter))
848     max_jitter = iface->cnf->hello_params.emission_interval / 4;
849
850   /* Recalculate max topology hold time */
851   if(max_tc_vtime < iface->cnf->tc_params.emission_interval)
852     max_tc_vtime = iface->cnf->tc_params.emission_interval;
853
854   ifp->hello_etime = double_to_me(iface->cnf->hello_params.emission_interval);
855   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
856   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
857   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
858   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
859
860
861   /*
862    *Call possible ifchange functions registered by plugins  
863    */
864   tmp_ifchgf_list = ifchgf_list;
865   while(tmp_ifchgf_list != NULL)
866     {
867       tmp_ifchgf_list->function(ifp, IFCHG_IF_ADD);
868       tmp_ifchgf_list = tmp_ifchgf_list->next;
869     }
870
871   return 1;
872 }
873
874
875
876 #ifdef linux
877 /**
878  *Check if a interface is wireless
879  *Returns 1 if no info can be gathered
880  *
881  *@param sock socket to use for kernel communication
882  *@param ifr a ifreq struct describing the interface
883  *
884  *@return 1 if interface is wireless(or no info was
885  *found) 0 if not.
886  */
887 int
888 check_wireless_interface(struct ifreq *ifr)
889 {
890   if(ioctl(ioctl_s, SIOCGIWNAME, ifr) >= 0)
891     {
892       return 1;
893     }
894   else
895     {
896       return 0;
897     }
898
899 }
900 #else
901 int check_wireless_interface(struct ifreq *ifr)
902 {
903   return 1;
904 }
905 #endif
906
907