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