* killed lots of #ifdef ... #endif which make the source quite unreadable
[olsrd.git] / src / unix / ifnet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41
42 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
43 #define ifr_netmask ifr_addr
44 #endif
45
46 #include "ifnet.h"
47 #include "ipcalc.h"
48 #include "interfaces.h"
49 #include "defs.h"
50 #include "olsr.h"
51 #include "net_os.h"
52 #include "net_olsr.h"
53 #include "socket_parser.h"
54 #include "parser.h"
55 #include "scheduler.h"
56 #include "generate_msg.h"
57 #include "mantissa.h"
58 #include "lq_packet.h"
59 #include "log.h"
60 #include "link_set.h"
61 #include <signal.h>
62 #include <sys/types.h>
63 #include <net/if.h>
64 #include <net/if_arp.h>
65 #include <netinet/in_systm.h>
66 #include <netinet/ip.h>
67 #include <arpa/inet.h>
68 #include <netdb.h>
69 #include <unistd.h>
70
71 #define BUFSPACE  (127*1024)    /* max. input buffer size to request */
72
73 int
74 set_flag(char *ifname, short flag __attribute__((unused)))
75 {
76   struct ifreq ifr;
77
78   strscpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
79
80   /* Get flags */
81   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
82     {
83       fprintf(stderr,"ioctl (get interface flags)");
84       return -1;
85     }
86
87   strscpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
88   
89   //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
90
91   if(!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)))
92     {
93       /* Add UP */
94       ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
95       /* Set flags + UP */
96       if(ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0)
97         {
98           fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
99           return -1;
100         }
101     }
102   return 1;
103
104 }
105
106
107
108
109 void
110 check_interface_updates(void *foo __attribute__((unused)))
111 {
112   struct olsr_if *tmp_if;
113
114 #ifdef DEBUG
115   OLSR_PRINTF(3, "Checking for updates in the interface set\n");
116 #endif
117
118   for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
119     {
120       if(tmp_if->host_emul)
121         continue;
122       
123       if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
124         continue;
125
126       if(!tmp_if->cnf->autodetect_chg) 
127         {
128 #ifdef DEBUG
129           /* Don't check this interface */
130           OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name);
131 #endif
132           continue;
133         }
134
135       if(tmp_if->configured)
136         {
137           chk_if_changed(tmp_if);
138         }
139       else
140         {
141           chk_if_up(tmp_if, 3);
142         }
143     }
144
145   return;
146 }
147
148 /**
149  * Checks if an initialized interface is changed
150  * that is if it has been set down or the address
151  * has been changed.
152  *
153  *@param iface the olsr_if struct describing the interface
154  */
155 int
156 chk_if_changed(struct olsr_if *iface)
157 {
158   struct interface *ifp, *tmp_ifp;
159   struct ifreq ifr;
160   struct sockaddr_in6 tmp_saddr6;
161   int if_changes;
162   if_changes = 0;
163
164 #ifdef DEBUG
165   OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
166 #endif
167
168   if(iface->host_emul)
169     return -1;
170
171   ifp = iface->interf;
172
173   if(ifp == NULL)
174     {
175       /* Should not happen */
176       iface->configured = 0;
177       return 0;
178     }
179
180   memset(&ifr, 0, sizeof(struct ifreq));
181   strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
182
183
184   /* Get flags (and check if interface exists) */
185   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
186     {
187       OLSR_PRINTF(3, "No such interface: %s\n", iface->name);
188       goto remove_interface;
189     }
190
191   ifp->int_flags = ifr.ifr_flags;
192
193   /*
194    * First check if the interface is set DOWN
195    */
196
197   if ((ifp->int_flags & IFF_UP) == 0)
198     {
199       OLSR_PRINTF(1, "\tInterface %s not up - removing it...\n", iface->name);
200       goto remove_interface;
201     }
202
203   /*
204    * We do all the interface type checks over.
205    * This is because the interface might be a PCMCIA card. Therefore
206    * It might not be the same physical interface as we configured earlier.
207    */
208
209   /* Check broadcast */
210   if ((olsr_cnf->ip_version == AF_INET) && 
211       !iface->cnf->ipv4_broadcast.v4.s_addr && /* Skip if fixed bcast */ 
212       (!(ifp->int_flags & IFF_BROADCAST))) 
213     {
214       OLSR_PRINTF(3, "\tNo broadcast - removing\n");
215       goto remove_interface;
216     }
217
218   if (ifp->int_flags & IFF_LOOPBACK)
219     {
220       OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n");
221       goto remove_interface;
222     }
223
224   ifp->is_hcif = OLSR_FALSE;
225
226   /* trying to detect if interface is wireless. */
227   ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
228
229   /* Set interface metric */
230   if(iface->cnf->weight.fixed)
231     ifp->int_metric = iface->cnf->weight.value;
232   else
233     ifp->int_metric = calculate_if_metric(ifr.ifr_name);
234
235   /* Get MTU */
236   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
237     ifp->int_mtu = 0;
238   else
239     {
240       ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
241
242       if(ifp->int_mtu != ifr.ifr_mtu)
243         {
244           ifp->int_mtu = ifr.ifr_mtu;
245           /* Create new outputbuffer */
246           net_remove_buffer(ifp); /* Remove old */
247           net_add_buffer(ifp);
248         }
249     }
250
251
252   /* Get interface index */
253   ifp->if_index = if_nametoindex(ifr.ifr_name);
254
255   /*
256    * Now check if the IP has changed
257    */
258   
259   /* IP version 6 */
260   if(olsr_cnf->ip_version == AF_INET6)
261     {
262 #ifdef DEBUG
263       struct ipaddr_str buf;
264 #endif
265       /* Get interface address */
266       
267       if(get_ipv6_address(ifr.ifr_name, &tmp_saddr6, iface->cnf->ipv6_addrtype) <= 0)
268         {
269           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
270             OLSR_PRINTF(3, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
271           else
272             OLSR_PRINTF(3, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
273           
274           
275           goto remove_interface;
276         }
277       
278 #ifdef DEBUG
279       OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
280 #endif
281
282       if(memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0)
283         {
284           struct ipaddr_str buf;
285           OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name);
286           OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&buf, &ifp->int6_addr.sin6_addr));
287           OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
288
289           /* Check main addr */
290           if(memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0)
291             {
292               /* Update main addr */
293               memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
294             }
295
296           /* Update address */
297           memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
298           memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
299
300           run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
301
302           return 1;               
303         }
304       return 0;
305
306     }
307   else
308   /* IP version 4 */
309     {
310       struct ipaddr_str buf;
311       /* Check interface address (IPv4)*/
312       if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) 
313         {
314           OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n");
315           goto remove_interface;
316         }
317
318 #ifdef DEBUG
319       OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
320 #endif
321
322       if(memcmp(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
323                 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
324                 olsr_cnf->ipsize) != 0)
325         {
326           /* New address */
327           OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name);
328           OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_addr.sin_addr));
329           OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
330
331           ifp->int_addr = *(struct sockaddr_in *)&ifr.ifr_addr;
332
333           if(memcmp(&olsr_cnf->main_addr, 
334                     &ifp->ip_addr,
335                     olsr_cnf->ipsize) == 0)
336             {
337               OLSR_PRINTF(1, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
338               olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
339               memcpy(&olsr_cnf->main_addr, 
340                      &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
341                      olsr_cnf->ipsize);
342             }
343
344           memcpy(&ifp->ip_addr, 
345                  &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
346                  olsr_cnf->ipsize);
347
348           if_changes = 1;
349         }
350
351       /* Check netmask */
352       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
353         {
354           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
355           goto remove_interface;
356         }
357
358 #ifdef DEBUG
359       OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
360 #endif
361
362       if(memcmp(&((struct sockaddr_in *)&ifp->int_netmask)->sin_addr.s_addr,
363                 &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, 
364                 olsr_cnf->ipsize) != 0)
365         {
366           struct ipaddr_str buf;
367           /* New address */
368           OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
369           OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_netmask.sin_addr));
370           OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
371
372           ifp->int_netmask = *(struct sockaddr_in *)&ifr.ifr_netmask;
373
374           if_changes = 1;
375         }
376       
377       if(!iface->cnf->ipv4_broadcast.v4.s_addr)
378         {
379           /* Check broadcast address */      
380           if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
381             {
382               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
383               goto remove_interface;
384             }
385           
386 #ifdef DEBUG
387           OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
388 #endif
389           
390           if(ifp->int_broadaddr.sin_addr.s_addr != ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr)
391             {
392               struct ipaddr_str buf;
393               /* New address */
394               OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
395               OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_broadaddr.sin_addr));
396               OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
397               
398               ifp->int_broadaddr = *(struct sockaddr_in *)&ifr.ifr_broadaddr;
399               if_changes = 1;
400             }            
401         }
402     }
403
404   if(if_changes)
405     run_ifchg_cbs(ifp, IFCHG_IF_UPDATE);
406
407   return if_changes;
408
409
410  remove_interface:
411   OLSR_PRINTF(1, "Removing interface %s\n", iface->name);
412   olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
413
414   olsr_delete_link_entry_by_ip(&ifp->ip_addr);
415
416   /*
417    *Call possible ifchange functions registered by plugins  
418    */
419   run_ifchg_cbs(ifp, IFCHG_IF_REMOVE);
420   
421   /* Dequeue */
422   if(ifp == ifnet)
423     {
424       ifnet = ifp->int_next;
425     }
426   else
427     {
428       tmp_ifp = ifnet;
429       while(tmp_ifp->int_next != ifp)
430         {
431           tmp_ifp = tmp_ifp->int_next;
432         }
433       tmp_ifp->int_next = ifp->int_next;
434     }
435
436
437   /* Remove output buffer */
438   net_remove_buffer(ifp);
439
440   /* Check main addr */
441   if(ipequal(&olsr_cnf->main_addr, &ifp->ip_addr))
442     {
443       if(ifnet == NULL)
444         {
445           /* No more interfaces */
446           memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
447           OLSR_PRINTF(1, "No more interfaces...\n");
448         }
449       else
450         {
451           struct ipaddr_str buf;
452           olsr_cnf->main_addr = ifnet->ip_addr;
453           OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
454           olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
455         }
456     }
457
458   /*
459    * Deregister functions for periodic message generation 
460    */
461   olsr_stop_timer(ifp->hello_gen_timer);
462   olsr_stop_timer(ifp->tc_gen_timer);
463   olsr_stop_timer(ifp->mid_gen_timer);
464   olsr_stop_timer(ifp->hna_gen_timer);
465
466   iface->configured = 0;
467   iface->interf = NULL;
468   /* Close olsr socket */
469   close(ifp->olsr_socket);
470   remove_olsr_socket(ifp->olsr_socket, &olsr_input);
471
472   /* Free memory */
473   free(ifp->int_name);
474   free(ifp);
475
476   if((ifnet == NULL) && (!olsr_cnf->allow_no_interfaces))
477     {
478       OLSR_PRINTF(1, "No more active interfaces - exiting.\n");
479       olsr_syslog(OLSR_LOG_INFO, "No more active interfaces - exiting.\n");
480       olsr_cnf->exit_value = EXIT_FAILURE;
481       kill(getpid(), SIGINT);
482     }
483
484   return 0;
485
486 }
487
488 /**
489  * Initializes the special interface used in
490  * host-client emulation
491  */
492 int
493 add_hemu_if(struct olsr_if *iface)
494 {
495   struct interface *ifp;
496   union olsr_ip_addr null_addr;
497   olsr_u32_t addr[4];
498   struct ipaddr_str buf;
499   size_t name_size;
500
501   if(!iface->host_emul)
502     return -1;
503
504   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
505
506   memset(ifp, 0, sizeof (struct interface));
507
508   iface->configured = OLSR_TRUE;
509   iface->interf = ifp;
510
511   name_size = strlen("hcif01") + 1;
512   ifp->is_hcif = OLSR_TRUE;
513   ifp->int_name = olsr_malloc(name_size, "Interface update 3");
514   ifp->int_metric = 0;
515
516   strscpy(ifp->int_name, "hcif01", name_size);
517
518   OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
519
520   OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
521
522   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
523
524   ifp->int_next = ifnet;
525   ifnet = ifp;
526
527   memset(&null_addr, 0, olsr_cnf->ipsize);
528   if(ipequal(&null_addr, &olsr_cnf->main_addr))
529     {
530       olsr_cnf->main_addr = iface->hemu_ip;
531       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
532         olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
533     }
534
535   ifp->int_mtu = OLSR_DEFAULT_MTU;
536
537   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
538
539   /* Set up buffer */
540   net_add_buffer(ifp);
541
542
543   if(olsr_cnf->ip_version == AF_INET)
544     {
545       struct sockaddr_in sin;
546
547       memset(&sin, 0, sizeof(sin));
548
549       sin.sin_family = AF_INET;
550       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
551       sin.sin_port = htons(10150);
552  
553      /* IP version 4 */
554       ifp->ip_addr.v4 = iface->hemu_ip.v4;
555
556       memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
557       
558       /*
559        *We create one socket for each interface and bind
560        *the socket to it. This to ensure that we can control
561        *on what interface the message is transmitted
562        */
563       
564       ifp->olsr_socket = gethemusocket(&sin);
565       
566       if (ifp->olsr_socket < 0)
567         {
568           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
569           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
570           olsr_cnf->exit_value = EXIT_FAILURE;
571           kill(getpid(), SIGINT);
572         }
573
574     }
575   else
576     {
577       /* IP version 6 */
578       memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
579
580 #if 0      
581       /*
582        *We create one socket for each interface and bind
583        *the socket to it. This to ensure that we can control
584        *on what interface the message is transmitted
585        */
586       
587       ifp->olsr_socket = gethcsocket6(&addrsock6, BUFSPACE, ifp->int_name);
588       
589       join_mcast(ifp, ifp->olsr_socket);
590       
591       if (ifp->olsr_socket < 0)
592         {
593           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
594           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
595           olsr_cnf->exit_value = EXIT_FAILURE;
596           kill(getpid(), SIGINT);
597         }
598       
599 #endif
600     }
601
602   /* Send IP as first 4/16 bytes on socket */
603   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
604   addr[0] = htonl(addr[0]);
605   addr[1] = htonl(addr[1]);
606   addr[2] = htonl(addr[2]);
607   addr[3] = htonl(addr[3]);
608
609   if(send(ifp->olsr_socket, addr , olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
610     {
611       fprintf(stderr, "Error sending IP!");
612     }  
613   
614   /* Register socket */
615   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
616
617
618   /*
619    * Register functions for periodic message generation 
620    */
621   
622   ifp->hello_gen_timer =
623     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC,
624                      HELLO_JITTER, OLSR_TIMER_PERIODIC,
625                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello,
626                      ifp, 0);
627   ifp->tc_gen_timer =
628     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC,
629                      TC_JITTER, OLSR_TIMER_PERIODIC,
630                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc,
631                      ifp, 0);
632   ifp->mid_gen_timer =
633     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC,
634                      MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp, 0);
635   ifp->hna_gen_timer =
636     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC,
637                      HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp, 0);
638
639   /* Recalculate max topology hold time */
640   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
641     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
642
643   ifp->hello_etime = (olsr_reltime)(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
644   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
645   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
646   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
647   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
648
649   return 1;
650 }
651
652 static char basenamestr[32];
653 static const char* if_basename(const char* name);
654 static const char* if_basename(const char* name)
655 {
656         char *p = strchr(name, ':');
657         if (NULL == p || p - name >= (int)(sizeof(basenamestr) / sizeof(basenamestr[0]) - 1)) {
658                 return name;
659         }
660         memcpy(basenamestr, name, p - name);
661         basenamestr[p - name] = 0;
662         return basenamestr;
663 }
664
665 /**
666  * Initializes a interface described by iface,
667  * if it is set up and is of the correct type.
668  *
669  *@param iface the olsr_if struct describing the interface
670  *@param so the socket to use for ioctls
671  *
672  */
673 int
674 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__((unused)))
675 {
676   struct interface ifs, *ifp;
677   struct ifreq ifr;
678   union olsr_ip_addr null_addr;
679   size_t name_size;
680 #ifdef linux
681   int precedence = IPTOS_PREC(olsr_cnf->tos);
682   int tos_bits = IPTOS_TOS(olsr_cnf->tos);
683 #endif
684
685   if(iface->host_emul)
686     return -1;
687
688   memset(&ifr, 0, sizeof(struct ifreq));
689   memset(&ifs, 0, sizeof(struct interface));
690   strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
691
692   OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
693
694   /* Get flags (and check if interface exists) */
695   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) 
696     {
697       OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
698       return 0;
699     }
700
701   ifs.int_flags = ifr.ifr_flags;      
702
703
704   if ((ifs.int_flags & IFF_UP) == 0)
705     {
706       OLSR_PRINTF(debuglvl, "\tInterface not up - skipping it...\n");
707       return 0;
708     }
709
710   /* Check broadcast */
711   if ((olsr_cnf->ip_version == AF_INET) &&
712       !iface->cnf->ipv4_broadcast.v4.s_addr && /* Skip if fixed bcast */ 
713       (!(ifs.int_flags & IFF_BROADCAST))) 
714     {
715       OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
716       return 0;
717     }
718
719
720   if (ifs.int_flags & IFF_LOOPBACK)
721     {
722       OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
723       return 0;
724     }
725
726   ifs.is_hcif = OLSR_FALSE;
727
728   /* trying to detect if interface is wireless. */
729   ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
730
731   if(ifs.is_wireless)
732     OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
733   else
734     OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
735
736   
737   /* IP version 6 */
738   if(olsr_cnf->ip_version == AF_INET6)
739     {
740       /* Get interface address */
741       struct ipaddr_str buf;
742       if(get_ipv6_address(ifr.ifr_name, &ifs.int6_addr, iface->cnf->ipv6_addrtype) <= 0)
743         {
744           if(iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL)
745             OLSR_PRINTF(debuglvl, "\tCould not find site-local IPv6 address for %s\n", ifr.ifr_name);
746           else
747             OLSR_PRINTF(debuglvl, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
748           
749           return 0;
750         }
751       
752       OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
753       
754       /* Multicast */
755       ifs.int6_multaddr.sin6_addr = (iface->cnf->ipv6_addrtype == IPV6_ADDR_SITELOCAL) ? 
756         iface->cnf->ipv6_multi_site.v6 :
757         iface->cnf->ipv6_multi_glbl.v6;
758       /* Set address family */
759       ifs.int6_multaddr.sin6_family = AF_INET6;
760       /* Set port */
761       ifs.int6_multaddr.sin6_port = htons(OLSRPORT);
762       
763 #ifdef __MacOSX__
764       ifs.int6_multaddr.sin6_scope_id = 0;
765 #endif
766
767       OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
768       
769     }
770   /* IP version 4 */
771   else
772     {
773       /* Get interface address (IPv4)*/
774       if(ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) 
775         {
776           OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
777           return 0;
778         }
779       
780       ifs.int_addr = *(struct sockaddr_in *)&ifr.ifr_addr;
781       
782       /* Find netmask */
783       
784       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) 
785         {
786           olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
787           return 0;
788         }
789       
790       ifs.int_netmask = *(struct sockaddr_in *)&ifr.ifr_netmask;
791       
792       /* Find broadcast address */
793       if(iface->cnf->ipv4_broadcast.v4.s_addr)
794         {
795           /* Specified broadcast */
796           memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, 
797                  &iface->cnf->ipv4_broadcast.v4, 
798                  sizeof(olsr_u32_t));
799         }
800       else
801         {
802           /* Autodetect */
803           if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) 
804             {
805               olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
806               return 0;
807             }
808           
809           ifs.int_broadaddr = *(struct sockaddr_in *)&ifr.ifr_broadaddr;
810         }
811       
812       /* Deactivate IP spoof filter */
813       deactivate_spoof(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
814       
815       /* Disable ICMP redirects */
816       disable_redirects(if_basename(ifr.ifr_name), &ifs, olsr_cnf->ip_version);
817       
818     }
819   
820   
821   /* Get interface index */
822   
823   ifs.if_index = if_nametoindex(ifr.ifr_name);
824   
825   /* Set interface metric */
826   if(iface->cnf->weight.fixed)
827     ifs.int_metric = iface->cnf->weight.value;
828   else
829     ifs.int_metric = calculate_if_metric(ifr.ifr_name);
830   OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
831
832   /* Get MTU */
833   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
834     ifs.int_mtu = OLSR_DEFAULT_MTU;
835   else
836     ifs.int_mtu = ifr.ifr_mtu;
837
838   ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
839
840   ifs.ttl_index = -32; /* For the first 32 TC's, fish-eye is disabled */
841
842   /* Set up buffer */
843   net_add_buffer(&ifs);
844                
845   OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
846
847   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
848   OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_index);
849
850   if(olsr_cnf->ip_version == AF_INET)
851     {
852       struct ipaddr_str buf;
853       OLSR_PRINTF(1, "\tAddress:%s\n", ip4_to_string(&buf, ifs.int_addr.sin_addr));
854       OLSR_PRINTF(1, "\tNetmask:%s\n", ip4_to_string(&buf, ifs.int_netmask.sin_addr));
855       OLSR_PRINTF(1, "\tBroadcast address:%s\n", ip4_to_string(&buf, ifs.int_broadaddr.sin_addr));
856     }
857   else
858     {
859       struct ipaddr_str buf;
860       OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
861       OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
862     }
863   
864   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
865   
866   ifp->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
867
868   iface->configured = 1;
869   iface->interf = ifp;
870
871   /* XXX bad code */
872   memcpy(ifp, &ifs, sizeof(struct interface));
873   
874   name_size = strlen(if_basename(ifr.ifr_name)) + 1;
875   ifp->gen_properties = NULL;
876   ifp->int_name = olsr_malloc(name_size, "Interface update 3");
877   strscpy(ifp->int_name, if_basename(ifr.ifr_name), name_size);
878   ifp->int_next = ifnet;
879   ifnet = ifp;
880
881   if(olsr_cnf->ip_version == AF_INET)
882     {
883       /* IP version 4 */
884       ifp->ip_addr.v4 = ifp->int_addr.sin_addr;
885       /*
886        *We create one socket for each interface and bind
887        *the socket to it. This to ensure that we can control
888        *on what interface the message is transmitted
889        */
890       
891       ifp->olsr_socket = getsocket(BUFSPACE, ifp->int_name);
892       
893       if (ifp->olsr_socket < 0)
894         {
895           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
896           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
897           olsr_cnf->exit_value = EXIT_FAILURE;
898           kill(getpid(), SIGINT);
899         }
900
901     }
902   else
903     {
904       /* IP version 6 */
905       ifp->ip_addr.v6 =  ifp->int6_addr.sin6_addr;
906       
907       /*
908        *We create one socket for each interface and bind
909        *the socket to it. This to ensure that we can control
910        *on what interface the message is transmitted
911        */
912       
913       ifp->olsr_socket = getsocket6(BUFSPACE, ifp->int_name);
914       
915       join_mcast(ifp, ifp->olsr_socket);
916       
917       if (ifp->olsr_socket < 0)
918         {
919           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
920           olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
921           olsr_cnf->exit_value = EXIT_FAILURE;
922           kill(getpid(), SIGINT);
923         }
924       
925     }
926
927   set_buffer_timer(ifp);
928
929   /* Register socket */
930   add_olsr_socket(ifp->olsr_socket, &olsr_input);
931   
932 #ifdef linux 
933   /* Set TOS */
934   
935   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char*)&precedence, sizeof(precedence)) < 0)
936     {
937       perror("setsockopt(SO_PRIORITY)");
938       olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
939     }
940   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char*)&tos_bits, sizeof(tos_bits)) < 0)    
941     {
942       perror("setsockopt(IP_TOS)");
943       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
944     }
945 #endif
946   
947   /*
948    *Initialize sequencenumber as a random 16bit value
949    */
950   ifp->olsr_seqnum = random() & 0xFFFF;
951
952   /*
953    * Set main address if this is the only interface
954    */
955   memset(&null_addr, 0, olsr_cnf->ipsize);
956   if(ipequal(&null_addr, &olsr_cnf->main_addr))
957     {
958       struct ipaddr_str buf;
959       olsr_cnf->main_addr = ifp->ip_addr;
960       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
961       olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
962     }
963   
964   /*
965    * Register functions for periodic message generation 
966    */
967   ifp->hello_gen_timer =
968     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC,
969                      HELLO_JITTER, OLSR_TIMER_PERIODIC,
970                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello,
971                      ifp, 0);
972   ifp->tc_gen_timer =
973     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC,
974                      TC_JITTER, OLSR_TIMER_PERIODIC,
975                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc,
976                      ifp, 0);
977   ifp->mid_gen_timer =
978     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC,
979                      MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp, 0);
980   ifp->hna_gen_timer =
981     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC,
982                      HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp, 0);
983
984   /* Recalculate max topology hold time */
985   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval) {
986     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
987   }
988   ifp->hello_etime = (olsr_reltime)(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
989   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
990   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
991   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
992   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
993
994
995   /*
996    *Call possible ifchange functions registered by plugins  
997    */
998   run_ifchg_cbs(ifp, IFCHG_IF_ADD);
999
1000   return 1;
1001 }
1002
1003 /*
1004  * Local Variables:
1005  * c-basic-offset: 2
1006  * End:
1007  */