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