Removed a non-portable whitespace
[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.2 2004/11/05 08:07:32 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__
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, 1);
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(1, "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(1, "\tNo broadcast - removing\n");
188       goto remove_interface;
189     }
190
191   if (ifp->int_flags & IFF_LOOPBACK)
192     {
193       olsr_printf(1, "\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(1, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
235           else
236             olsr_printf(1, "\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   olsr_remove_scheduler_event(&generate_hello, 
445                               ifp, 
446                               iface->cnf->hello_params.emission_interval, 
447                               0, 
448                               NULL);
449   olsr_remove_scheduler_event(&generate_tc, 
450                               ifp, 
451                               iface->cnf->tc_params.emission_interval,
452                               0, 
453                               NULL);
454 #else
455   olsr_remove_scheduler_event(&olsr_output_lq_hello, 
456                               ifp, 
457                               iface->cnf->hello_params.emission_interval, 
458                               0, 
459                               NULL);
460   olsr_remove_scheduler_event(&olsr_output_lq_tc, 
461                               ifp, 
462                               iface->cnf->tc_params.emission_interval,
463                               0, 
464                               NULL);
465 #endif
466   olsr_remove_scheduler_event(&generate_mid, 
467                               ifp, 
468                               iface->cnf->mid_params.emission_interval,
469                               0, 
470                               NULL);
471   olsr_remove_scheduler_event(&generate_hna, 
472                               ifp, 
473                               iface->cnf->hna_params.emission_interval,
474                               0, 
475                               NULL);
476
477
478
479   iface->configured = 0;
480   iface->interf = NULL;
481   /* Close olsr socket */
482   close(ifp->olsr_socket);
483   remove_olsr_socket(ifp->olsr_socket, &olsr_input);
484   /* Free memory */
485   free(ifp->int_name);
486   free(ifp);
487
488   if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
489     {
490       olsr_printf(1, "No more active interfaces - exiting.\n");
491       olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
492       exit_value = EXIT_FAILURE;
493       kill(getpid(), SIGINT);
494     }
495
496   return 0;
497
498 }
499
500
501
502 /**
503  * Initializes a interface described by iface,
504  * if it is set up and is of the correct type.
505  *
506  *@param iface the olsr_if struct describing the interface
507  *@param so the socket to use for ioctls
508  *
509  */
510 int
511 chk_if_up(struct olsr_if *iface, int debuglvl)
512 {
513   struct interface ifs, *ifp;
514   struct ifreq ifr;
515   union olsr_ip_addr null_addr;
516   struct ifchgf *tmp_ifchgf_list;
517 #ifdef linux
518   int precedence = IPTOS_PREC(olsr_cnf->tos);
519   int tos_bits = IPTOS_TOS(olsr_cnf->tos);
520 #endif
521
522   memset(&ifr, 0, sizeof(struct ifreq));
523   strncpy(ifr.ifr_name, iface->name, IFNAMSIZ);
524
525   olsr_printf(debuglvl, "Checking %s:\n", ifr.ifr_name);
526
527   /* Get flags (and check if interface exists) */
528   if (ioctl(ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
529     {
530       olsr_printf(debuglvl, "\tNo such interface!\n");
531       return 0;
532     }
533
534   ifs.int_flags = ifr.ifr_flags | IFF_INTERFACE;      
535
536
537   if ((ifs.int_flags & IFF_UP) == 0)
538     {
539       olsr_printf(debuglvl, "\tInterface not up - skipping it...\n");
540       return 0;
541     }
542
543   /* Check broadcast */
544   if ((olsr_cnf->ip_version == AF_INET) && (!(ifs.int_flags & IFF_BROADCAST))) 
545     {
546       olsr_printf(debuglvl, "\tNo broadcast - skipping\n");
547       return 0;
548     }
549
550
551   if (ifs.int_flags & IFF_LOOPBACK)
552     {
553       olsr_printf(debuglvl, "\tThis is a loopback interface - skipping it...\n");
554       return 0;
555     }
556
557   /* trying to detect if interface is wireless. */
558   if(check_wireless_interface(&ifr))
559     {
560       olsr_printf(debuglvl, "\tWireless interface detected\n");
561       ifs.is_wireless = 1;
562     }
563   else
564     {
565       olsr_printf(debuglvl, "\tNot a wireless interface\n");
566       ifs.is_wireless = 0;
567     }
568
569   
570   /* IP version 6 */
571   if(olsr_cnf->ip_version == AF_INET6)
572     {
573       /* Get interface address */
574       
575       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
576         {
577           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
578             olsr_printf(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
579           else
580             olsr_printf(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
581           
582           return 0;
583         }
584       
585       olsr_printf(debuglvl, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
586       
587       /* Multicast */
588       ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == 1) ? iface->cnf->ipv6_multi_site.v6 :iface->cnf->ipv6_multi_site.v6;
589       /* Set address family */
590       ifs.int6_multaddr.sin6_family = AF_INET6;
591       /* Set port */
592       ifs.int6_multaddr.sin6_port = olsr_udp_port;
593       
594       olsr_printf(debuglvl, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
595       
596     }
597   /* IP version 4 */
598   else
599     {
600       /* Get interface address (IPv4)*/
601       if(ioctl(ioctl_s, SIOCGIFADDR, &ifr) < 0) 
602         {
603           olsr_printf(debuglvl, "\tCould not get address of interface - skipping it\n");
604           return 0;
605         }
606       
607       ifs.int_addr = ifr.ifr_addr;
608       
609       /* Find netmask */
610       
611       if (ioctl(ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
612         {
613           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
614           return 0;
615         }
616       
617       ifs.int_netmask = ifr.ifr_netmask;
618       
619       /* Find broadcast address */
620       if(iface->cnf->ipv4_broadcast.v4)
621         {
622           /* Specified broadcast */
623           memset(&ifs.int_broadaddr, 0, sizeof(struct sockaddr));
624           memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, 
625                  &iface->cnf->ipv4_broadcast.v4, 
626                  sizeof(olsr_u32_t));
627         }
628       else
629         {
630           /* Autodetect */
631           if (ioctl(ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
632             {
633               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
634               return 0;
635             }
636           
637           ifs.int_broadaddr = ifr.ifr_broadaddr;
638         }
639       
640       /* Deactivate IP spoof filter */
641       deactivate_spoof(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
642       
643       /* Disable ICMP redirects */
644       disable_redirects(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
645       
646     }
647   
648   
649   /* Get interface index */
650   
651   ifs.if_index = if_nametoindex(ifr.ifr_name);
652   
653   /* Set interface metric */
654   ifs.int_metric = ifs.is_wireless;
655   
656   /* setting the interfaces number*/
657   ifs.if_nr = iface->index;
658
659
660   /* Get MTU */
661   if (ioctl(ioctl_s, SIOCGIFMTU, &ifr) < 0)
662     ifs.int_mtu = OLSR_DEFAULT_MTU;
663   else
664     ifs.int_mtu = ifr.ifr_mtu;
665
666   /* Set up buffer */
667   net_add_buffer(&ifs);
668                
669   olsr_printf(1, "\tMTU: %d\n", ifs.int_mtu);
670
671   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
672   olsr_printf(1, "\tInterface %s set up for use with index %d\n", iface->name, ifs.if_nr);
673
674   if(olsr_cnf->ip_version == AF_INET)
675     {
676       olsr_printf(1, "\tAddress:%s\n", sockaddr_to_string(&ifs.int_addr));
677       olsr_printf(1, "\tNetmask:%s\n", sockaddr_to_string(&ifs.int_netmask));
678       olsr_printf(1, "\tBroadcast address:%s\n", sockaddr_to_string(&ifs.int_broadaddr));
679     }
680   else
681     {
682       olsr_printf(1, "\tAddress: %s\n", ip6_to_string(&ifs.int6_addr.sin6_addr));
683       olsr_printf(1, "\tMulticast: %s\n", ip6_to_string(&ifs.int6_multaddr.sin6_addr));
684     }
685   
686   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
687   
688   iface->configured = 1;
689   iface->interf = ifp;
690   
691   memcpy(ifp, &ifs, sizeof(struct interface));
692   
693   ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
694       
695   strcpy(ifp->int_name, ifr.ifr_name);
696   /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
697   ifp->int_next = ifnet;
698   ifnet = ifp;
699
700   if(olsr_cnf->ip_version == AF_INET)
701     {
702       /* IP version 4 */
703       ifp->ip_addr.v4 = ((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr;
704       
705       /*
706        *We create one socket for each interface and bind
707        *the socket to it. This to ensure that we can control
708        *on what interface the message is transmitted
709        */
710       
711       ifp->olsr_socket = getsocket((struct sockaddr *)&addrsock, bufspace, ifp->int_name);
712       
713       if (ifp->olsr_socket < 0)
714         {
715           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
716           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
717           exit_value = EXIT_FAILURE;
718           kill(getpid(), SIGINT);
719         }
720     }
721   else
722     {
723       /* IP version 6 */
724       memcpy(&ifp->ip_addr, &ifp->int6_addr.sin6_addr, ipsize);
725
726       
727       /*
728        *We create one socket for each interface and bind
729        *the socket to it. This to ensure that we can control
730        *on what interface the message is transmitted
731        */
732       
733       ifp->olsr_socket = getsocket6(&addrsock6, bufspace, ifp->int_name);
734       
735       join_mcast(ifp, ifp->olsr_socket);
736       
737       if (ifp->olsr_socket < 0)
738         {
739           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
740           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
741           exit_value = EXIT_FAILURE;
742           kill(getpid(), SIGINT);
743         }
744       
745     }
746   
747   /* Register socket */
748   add_olsr_socket(ifp->olsr_socket, &olsr_input);
749   
750 #if defined linux 
751   /* Set TOS */
752   
753   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
754     {
755       perror("setsockopt(SO_PRIORITY)");
756       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
757     }
758   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
759     {
760       perror("setsockopt(IP_TOS)");
761       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
762     }
763 #endif
764   
765   /*
766    *Initialize sequencenumber as a random 16bit value
767    */
768   ifp->olsr_seqnum = random() & 0xFFFF;
769
770   /*
771    * Set main address if this is the only interface
772    */
773   memset(&null_addr, 0, ipsize);
774   if(COMP_IP(&null_addr, &main_addr))
775     {
776       COPY_IP(&main_addr, &ifp->ip_addr);
777       olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
778       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&main_addr));
779     }
780   
781   /*
782    * Register scheduled functions 
783    */
784 #if !defined USE_LINK_QUALITY
785   olsr_register_scheduler_event(&generate_hello, 
786                                 ifp, 
787                                 iface->cnf->hello_params.emission_interval, 
788                                 0, 
789                                 NULL);
790   olsr_register_scheduler_event(&generate_tc, 
791                                 ifp, 
792                                 iface->cnf->tc_params.emission_interval,
793                                 0, 
794                                 NULL);
795 #else
796   olsr_register_scheduler_event(&olsr_output_lq_hello, 
797                                 ifp, 
798                                 iface->cnf->hello_params.emission_interval, 
799                                 0, 
800                                 NULL);
801   olsr_register_scheduler_event(&olsr_output_lq_tc, 
802                                 ifp, 
803                                 iface->cnf->tc_params.emission_interval,
804                                 0, 
805                                 NULL);
806 #endif
807   olsr_register_scheduler_event(&generate_mid, 
808                                 ifp, 
809                                 iface->cnf->mid_params.emission_interval,
810                                 0, 
811                                 NULL);
812   olsr_register_scheduler_event(&generate_hna, 
813                                 ifp, 
814                                 iface->cnf->hna_params.emission_interval,
815                                 0, 
816                                 NULL);
817
818   /* Recalculate max jitter */
819
820   if((max_jitter == 0) || ((iface->cnf->hello_params.emission_interval / 4) < max_jitter))
821     max_jitter = iface->cnf->hello_params.emission_interval / 4;
822
823   /* Recalculate max topology hold time */
824   if(max_tc_vtime < iface->cnf->tc_params.emission_interval)
825     max_tc_vtime = iface->cnf->tc_params.emission_interval;
826
827   ifp->hello_etime = double_to_me(iface->cnf->hello_params.emission_interval);
828   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
829   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
830   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
831   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
832
833
834   /*
835    *Call possible ifchange functions registered by plugins  
836    */
837   tmp_ifchgf_list = ifchgf_list;
838   while(tmp_ifchgf_list != NULL)
839     {
840       tmp_ifchgf_list->function(ifp, IFCHG_IF_ADD);
841       tmp_ifchgf_list = tmp_ifchgf_list->next;
842     }
843
844   return 1;
845 }
846
847
848
849 #ifdef linux
850 /**
851  *Check if a interface is wireless
852  *Returns 1 if no info can be gathered
853  *
854  *@param sock socket to use for kernel communication
855  *@param ifr a ifreq struct describing the interface
856  *
857  *@return 1 if interface is wireless(or no info was
858  *found) 0 if not.
859  */
860 int
861 check_wireless_interface(struct ifreq *ifr)
862 {
863   if(ioctl(ioctl_s, SIOCGIWNAME, ifr) >= 0)
864     {
865       return 1;
866     }
867   else
868     {
869       return 0;
870     }
871
872 }
873 #else
874 int check_wireless_interface(struct ifreq *ifr)
875 {
876   return 1;
877 }
878 #endif
879
880