3e5f73b2275f2bd17b8b64f2b42107a0b327f402
[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.7 2004/11/21 10:50:52 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__
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 #if defined USE_LINK_QUALITY
459   if (olsr_cnf->lq_level == 0)
460     {
461 #endif
462       olsr_remove_scheduler_event(&generate_hello, 
463                                   ifp, 
464                                   iface->cnf->hello_params.emission_interval, 
465                                   0, 
466                                   NULL);
467       olsr_remove_scheduler_event(&generate_tc, 
468                                   ifp, 
469                                   iface->cnf->tc_params.emission_interval,
470                                   0, 
471                                   NULL);
472 #if defined USE_LINK_QUALITY
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 #endif
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) && (!(ifs.int_flags & IFF_BROADCAST))) 
568     {
569       olsr_printf(debuglvl, "\tNo broadcast - skipping\n");
570       return 0;
571     }
572
573
574   if (ifs.int_flags & IFF_LOOPBACK)
575     {
576       olsr_printf(debuglvl, "\tThis is a loopback interface - skipping it...\n");
577       return 0;
578     }
579
580   /* trying to detect if interface is wireless. */
581   if(check_wireless_interface(&ifr))
582     {
583       olsr_printf(debuglvl, "\tWireless interface detected\n");
584       ifs.is_wireless = 1;
585     }
586   else
587     {
588       olsr_printf(debuglvl, "\tNot a wireless interface\n");
589       ifs.is_wireless = 0;
590     }
591
592   
593   /* IP version 6 */
594   if(olsr_cnf->ip_version == AF_INET6)
595     {
596       /* Get interface address */
597       
598       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
599         {
600           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
601             olsr_printf(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
602           else
603             olsr_printf(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
604           
605           return 0;
606         }
607       
608       olsr_printf(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
609       
610       /* Multicast */
611       ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == 1) ? iface->cnf->ipv6_multi_site.v6 :iface->cnf->ipv6_multi_site.v6;
612       /* Set address family */
613       ifs.int6_multaddr.sin6_family = AF_INET6;
614       /* Set port */
615       ifs.int6_multaddr.sin6_port = olsr_udp_port;
616       
617       olsr_printf(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
618       
619     }
620   /* IP version 4 */
621   else
622     {
623       /* Get interface address (IPv4)*/
624       if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0) 
625         {
626           olsr_printf(debuglvl, "\tCould not get address of interface - skipping it\n");
627           return 0;
628         }
629       
630       ifs.int_addr = ifr.ifr_addr;
631       
632       /* Find netmask */
633       
634       if (ioctl(ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
635         {
636           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
637           return 0;
638         }
639       
640       ifs.int_netmask = ifr.ifr_netmask;
641       
642       /* Find broadcast address */
643       if(iface->cnf->ipv4_broadcast.v4)
644         {
645           /* Specified broadcast */
646           memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
647           memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, 
648                  &iface->cnf->ipv4_broadcast.v4, 
649                  sizeof(olsr_u32_t));
650         }
651       else
652         {
653           /* Autodetect */
654           if (ioctl(ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
655             {
656               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
657               return 0;
658             }
659           
660           ifs.int_broadaddr = ifr.ifr_broadaddr;
661         }
662       
663       /* Deactivate IP spoof filter */
664       deactivate_spoof(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
665       
666       /* Disable ICMP redirects */
667       disable_redirects(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
668       
669     }
670   
671   
672   /* Get interface index */
673   
674   ifs.if_index = if_nametoindex(ifr.ifr_name);
675   
676   /* Set interface metric */
677   ifs.int_metric = ifs.is_wireless;
678   
679   /* setting the interfaces number*/
680   ifs.if_nr = iface->index;
681
682
683   /* Get MTU */
684   if (ioctl(ioctl_s, SIOCGIFMTU, &ifr) < 0)
685     ifs.int_mtu = OLSR_DEFAULT_MTU;
686   else
687     ifs.int_mtu = ifr.ifr_mtu;
688
689   /* Set up buffer */
690   net_add_buffer(&ifs);
691                
692   olsr_printf(1, "\tMTU: %d\n", ifs.int_mtu);
693
694   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
695   olsr_printf(1, "\tInterface %s set up for use with index %d\n", iface->name, ifs.if_nr);
696
697   if(olsr_cnf->ip_version == AF_INET)
698     {
699       olsr_printf(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr));
700       olsr_printf(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask));
701       olsr_printf(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr));
702     }
703   else
704     {
705       olsr_printf(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
706       olsr_printf(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
707     }
708   
709   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
710   
711   iface->configured = 1;
712   iface->interf = ifp;
713   
714   memcpy(ifp, &ifs, sizeof(struct interface));
715   
716   ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
717       
718   strcpy(ifp->int_name, ifr.ifr_name);
719   /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
720   ifp->int_next = ifnet;
721   ifnet = ifp;
722
723   if(olsr_cnf->ip_version == AF_INET)
724     {
725       /* IP version 4 */
726       ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
727       
728       /*
729        *We create one socket for each interface and bind
730        *the socket to it. This to ensure that we can control
731        *on what interface the message is transmitted
732        */
733       
734       ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
735       
736       if (ifp->olsr_socket < 0)
737         {
738           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
739           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
740           exit_value = EXIT_FAILURE;
741           kill(getpid(), SIGINT);
742         }
743     }
744   else
745     {
746       /* IP version 6 */
747       memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, ipsize);
748
749       
750       /*
751        *We create one socket for each interface and bind
752        *the socket to it. This to ensure that we can control
753        *on what interface the message is transmitted
754        */
755       
756       ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
757       
758       join_mcast(ifp, ifp->olsr_socket);
759       
760       if (ifp->olsr_socket < 0)
761         {
762           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
763           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
764           exit_value = EXIT_FAILURE;
765           kill(getpid(), SIGINT);
766         }
767       
768     }
769   
770   /* Register socket */
771   add_olsr_socket(ifp->olsr_socket, &olsr_input);
772   
773 #ifdef linux 
774   /* Set TOS */
775   
776   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
777     {
778       perror("setsockopt(SO_PRIORITY)");
779       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
780     }
781   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
782     {
783       perror("setsockopt(IP_TOS)");
784       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
785     }
786 #endif
787   
788   /*
789    *Initialize sequencenumber as a random 16bit value
790    */
791   ifp->olsr_seqnum = random() & 0xFFFF;
792
793   /*
794    * Set main address if this is the only interface
795    */
796   memset(&null_addr, 0, ipsize);
797   if(COMP_IP(&null_addr, &main_addr))
798     {
799       COPY_IP(&main_addr, &ifp->ip_addr);
800       olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
801       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&main_addr));
802     }
803   
804   /*
805    * Register scheduled functions 
806    */
807 #if defined USE_LINK_QUALITY
808   if (olsr_cnf->lq_level == 0)
809     {
810 #endif
811       olsr_register_scheduler_event(&generate_hello, 
812                                     ifp, 
813                                     iface->cnf->hello_params.emission_interval, 
814                                     0, 
815                                     NULL);
816       olsr_register_scheduler_event(&generate_tc, 
817                                     ifp, 
818                                     iface->cnf->tc_params.emission_interval,
819                                     0, 
820                                     NULL);
821 #if defined USE_LINK_QUALITY
822     }
823
824   else
825     {
826       olsr_register_scheduler_event(&olsr_output_lq_hello, 
827                                     ifp, 
828                                     iface->cnf->hello_params.emission_interval, 
829                                     0, 
830                                     NULL);
831       olsr_register_scheduler_event(&olsr_output_lq_tc, 
832                                     ifp, 
833                                     iface->cnf->tc_params.emission_interval,
834                                     0, 
835                                     NULL);
836     }
837 #endif
838   olsr_register_scheduler_event(&generate_mid, 
839                                 ifp, 
840                                 iface->cnf->mid_params.emission_interval,
841                                 0, 
842                                 NULL);
843   olsr_register_scheduler_event(&generate_hna, 
844                                 ifp, 
845                                 iface->cnf->hna_params.emission_interval,
846                                 0, 
847                                 NULL);
848
849   /* Recalculate max jitter */
850
851   if((max_jitter == 0) || ((iface->cnf->hello_params.emission_interval / 4) < max_jitter))
852     max_jitter = iface->cnf->hello_params.emission_interval / 4;
853
854   /* Recalculate max topology hold time */
855   if(max_tc_vtime < iface->cnf->tc_params.emission_interval)
856     max_tc_vtime = iface->cnf->tc_params.emission_interval;
857
858   ifp->hello_etime = double_to_me(iface->cnf->hello_params.emission_interval);
859   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
860   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
861   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
862   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
863
864
865   /*
866    *Call possible ifchange functions registered by plugins  
867    */
868   tmp_ifchgf_list = ifchgf_list;
869   while(tmp_ifchgf_list != NULL)
870     {
871       tmp_ifchgf_list->function(ifp, IFCHG_IF_ADD);
872       tmp_ifchgf_list = tmp_ifchgf_list->next;
873     }
874
875   return 1;
876 }
877
878
879
880 #ifdef linux
881 /**
882  *Check if a interface is wireless
883  *Returns 1 if no info can be gathered
884  *
885  *@param sock socket to use for kernel communication
886  *@param ifr a ifreq struct describing the interface
887  *
888  *@return 1 if interface is wireless(or no info was
889  *found) 0 if not.
890  */
891 int
892 check_wireless_interface(struct ifreq *ifr)
893 {
894   if(ioctl(ioctl_s, SIOCGIWNAME, ifr) >= 0)
895     {
896       return 1;
897     }
898   else
899     {
900       return 0;
901     }
902
903 }
904 #else
905 int check_wireless_interface(struct ifreq *ifr)
906 {
907   return 1;
908 }
909 #endif
910
911