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