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