9eeeb9c87ca8e1f21174bd42cff36f4337a13f8a
[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 "parser.h"
54 #include "scheduler.h"
55 #include "generate_msg.h"
56 #include "mantissa.h"
57 #include "lq_packet.h"
58 #include "log.h"
59 #include "link_set.h"
60
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 || (ifp->int_flags & IFF_RUNNING) == 0) {
184     OLSR_PRINTF(1, "\tInterface %s not up and running - 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_multicast.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 dst interface address */
242
243     if (0 == get_ipv6_address(iface->name, &tmp_saddr6, (iface->cnf->ipv6_src.prefix_len == 0) ? NULL : (&iface->cnf->ipv6_src))) {
244       OLSR_PRINTF(3, "\tCould not find ip address for %s with prefix %s.\n", ifr.ifr_name, olsr_ip_prefix_to_string(&iface->cnf->ipv6_src));
245       goto remove_interface;
246     }
247
248 #ifdef DEBUG
249     OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&buf, &iface->cnf->ipv6_multicast.v6));
250 #endif
251
252     if (memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0) {
253       OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name);
254       OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&buf, &ifp->int6_addr.sin6_addr));
255       OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
256
257       /* deactivated to prevent change of originator IP */
258 #if 0
259       /* Check main addr */
260       if (memcmp(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize) == 0) {
261         /* Update main addr */
262         memcpy(&olsr_cnf->main_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
263       }
264 #endif
265       /* Update address */
266       memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
267       memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
268
269       olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_UPDATE);
270
271       /* we have to make sure that olsrd uses the new source address of this interface */
272       olsr_remove_interface(iface); /* so we remove the interface completely */
273       chk_if_up(iface,3); /* and create it again to get new sockets,..*/
274     }
275     return 0;
276
277   } else
278     /* IP version 4 */
279   {
280     struct ipaddr_str buf;
281     /* Check interface address (IPv4) */
282     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
283       OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n");
284       goto remove_interface;
285     }
286 #ifdef DEBUG
287     OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
288 #endif
289
290     if (memcmp
291         (&((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,
292          olsr_cnf->ipsize) != 0) {
293       /* New address */
294       OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name);
295       OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_addr.sin_addr));
296       OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
297
298       ifp->int_addr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_addr);
299       /* deactivated to prevent change of originator IP */
300 #if 0
301       if (memcmp(&olsr_cnf->main_addr, &ifp->ip_addr, olsr_cnf->ipsize) == 0) {
302         OLSR_PRINTF(1, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
303         olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
304         memcpy(&olsr_cnf->main_addr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, olsr_cnf->ipsize);
305       }
306 #endif
307       memcpy(&ifp->ip_addr, &((struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_addr))->sin_addr.s_addr, olsr_cnf->ipsize);
308
309       /* we have to make sure that olsrd uses the new source address of this interface */
310       olsr_remove_interface(iface); /* so we remove the interface completely */
311       chk_if_up(iface,3); /* and create it again to get new sockets,..*/
312       return 0;
313     }
314
315     /* Check netmask */
316     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
317       olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
318       goto remove_interface;
319     }
320 #ifdef DEBUG
321     OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
322 #endif
323
324     if (memcmp
325         (&((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,
326          olsr_cnf->ipsize) != 0) {
327       /* New address */
328       OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
329       OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_netmask.sin_addr));
330       OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
331
332       ifp->int_netmask = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_netmask);
333
334       if_changes = 1;
335     }
336
337     if (!iface->cnf->ipv4_multicast.v4.s_addr) {
338       /* Check broadcast address */
339       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) {
340         olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
341         goto remove_interface;
342       }
343 #ifdef DEBUG
344       OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
345 #endif
346
347       if (ifp->int_broadaddr.sin_addr.s_addr != ((struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr))->sin_addr.s_addr) {
348         /* New address */
349         OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
350         OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_broadaddr.sin_addr));
351         OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
352
353         ifp->int_broadaddr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr);
354         if_changes = 1;
355       }
356     }
357   }
358
359   if (if_changes)
360     olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_UPDATE);
361
362   return if_changes;
363
364 remove_interface:
365
366   olsr_remove_interface(iface);
367   return 0;
368 }
369
370 /**
371  * Initializes the special interface used in
372  * host-client emulation
373  */
374 int
375 add_hemu_if(struct olsr_if *iface)
376 {
377   struct interface *ifp;
378   union olsr_ip_addr null_addr;
379   uint32_t addr[4];
380   struct ipaddr_str buf;
381   size_t name_size;
382
383   if (!iface->host_emul)
384     return -1;
385
386   ifp = olsr_malloc(sizeof(struct interface), "Interface update 2");
387
388   memset(ifp, 0, sizeof(struct interface));
389
390   /* initialize backpointer */
391   ifp->olsr_if = iface;
392
393   iface->configured = true;
394   iface->interf = ifp;
395
396   name_size = strlen("hcif01") + 1;
397   ifp->is_hcif = true;
398   ifp->int_name = olsr_malloc(name_size, "Interface update 3");
399   ifp->int_metric = 0;
400
401   strscpy(ifp->int_name, "hcif01", name_size);
402
403   OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
404
405   OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
406
407   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
408
409   ifp->int_next = ifnet;
410   ifnet = ifp;
411
412   memset(&null_addr, 0, olsr_cnf->ipsize);
413   if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
414     olsr_cnf->main_addr = iface->hemu_ip;
415     olsr_cnf->unicast_src_ip = iface->hemu_ip;
416     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
417     olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
418   }
419
420   ifp->int_mtu = OLSR_DEFAULT_MTU;
421
422   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
423
424   /* Set up buffer */
425   net_add_buffer(ifp);
426
427   if (olsr_cnf->ip_version == AF_INET) {
428     struct sockaddr_in sin;
429
430     memset(&sin, 0, sizeof(sin));
431
432     sin.sin_family = AF_INET;
433     sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
434     sin.sin_port = htons(10150);
435
436     /* IP version 4 */
437     ifp->ip_addr.v4 = iface->hemu_ip.v4;
438
439     memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
440
441     /*
442      *We create one socket for each interface and bind
443      *the socket to it. This to ensure that we can control
444      *on what interface the message is transmitted
445      */
446
447     ifp->olsr_socket = gethemusocket(&sin);
448
449     if (ifp->olsr_socket < 0) {
450       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
451       olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
452       olsr_cnf->exit_value = EXIT_FAILURE;
453       kill(getpid(), SIGINT);
454     }
455
456   } else {
457     /* IP version 6 */
458     memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
459
460 #if 0
461     /*
462      *We create one socket for each interface and bind
463      *the socket to it. This to ensure that we can control
464      *on what interface the message is transmitted
465      */
466
467     ifp->olsr_socket = gethcsocket6(&addrsock6, BUFSPACE, ifp->int_name);
468
469     join_mcast(ifp, ifp->olsr_socket);
470
471     if (ifp->olsr_socket < 0) {
472       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
473       olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
474       olsr_cnf->exit_value = EXIT_FAILURE;
475       kill(getpid(), SIGINT);
476     }
477 #endif
478   }
479
480   /* Send IP as first 4/16 bytes on socket */
481   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
482   addr[0] = htonl(addr[0]);
483   addr[1] = htonl(addr[1]);
484   addr[2] = htonl(addr[2]);
485   addr[3] = htonl(addr[3]);
486
487   if (send(ifp->olsr_socket, addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize) {
488     fprintf(stderr, "Error sending IP!");
489   }
490
491   /* Register socket */
492   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu, NULL, NULL, SP_PR_READ);
493
494   /*
495    * Register functions for periodic message generation
496    */
497
498   ifp->hello_gen_timer =
499     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
500                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
501   ifp->tc_gen_timer =
502     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
503                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
504   ifp->mid_gen_timer =
505     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
506                      mid_gen_timer_cookie);
507   ifp->hna_gen_timer =
508     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
509                      hna_gen_timer_cookie);
510
511   /* Recalculate max topology hold time */
512   if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
513     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
514
515   ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
516   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
517   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
518   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
519   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
520
521   ifp->mode = iface->cnf->mode;
522
523   return 1;
524 }
525
526 static char basenamestr[32];
527 static const char *if_basename(const char *name);
528 static const char *
529 if_basename(const char *name)
530 {
531   char *p = strchr(name, ':');
532   if (NULL == p || p - name >= (int)(sizeof(basenamestr) / sizeof(basenamestr[0]) - 1)) {
533     return name;
534   }
535   memcpy(basenamestr, name, p - name);
536   basenamestr[p - name] = 0;
537   return basenamestr;
538 }
539
540 /**
541  * Initializes a interface described by iface,
542  * if it is set up and is of the correct type.
543  *
544  *@param iface the olsr_if struct describing the interface
545  *@param so the socket to use for ioctls
546  *
547  */
548 int
549 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
550 {
551   struct interface ifs, *ifp;
552   struct ifreq ifr;
553   union olsr_ip_addr null_addr;
554   size_t name_size;
555 #ifdef linux
556   int precedence = IPTOS_PREC(olsr_cnf->tos);
557   int tos_bits = IPTOS_TOS(olsr_cnf->tos);
558 #endif
559
560   if (iface->host_emul)
561     return -1;
562
563   memset(&ifr, 0, sizeof(struct ifreq));
564   memset(&ifs, 0, sizeof(struct interface));
565   strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
566
567   OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
568
569   /* Get flags (and check if interface exists) */
570   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
571     OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
572     return 0;
573   }
574
575   ifs.int_flags = ifr.ifr_flags;
576
577   if ( ( (ifs.int_flags & IFF_UP) == 0) || ( (ifs.int_flags & IFF_RUNNING) == 0) ) {
578     OLSR_PRINTF(debuglvl, "\tInterface not up & running - skipping it...\n");
579     return 0;
580   }
581
582   /* Check broadcast */
583   if ((olsr_cnf->ip_version == AF_INET) && !iface->cnf->ipv4_multicast.v4.s_addr &&     /* Skip if fixed bcast */
584       (!(ifs.int_flags & IFF_BROADCAST))) {
585     OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
586     return 0;
587   }
588
589   if (ifs.int_flags & IFF_LOOPBACK) {
590     OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
591     return 0;
592   }
593
594   ifs.is_hcif = false;
595
596   /* trying to detect if interface is wireless. */
597   ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
598
599   if (ifs.is_wireless)
600     OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
601   else
602     OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
603
604   /* IP version 6 */
605   if (olsr_cnf->ip_version == AF_INET6) {
606     /* Get interface address */
607     struct ipaddr_str buf;
608
609     if (0 == get_ipv6_address(iface->name, &ifs.int6_addr, (iface->cnf->ipv6_src.prefix_len == 0) ? NULL : (&iface->cnf->ipv6_src))) {
610       OLSR_PRINTF(3, "\tCould not find ip address for %s with prefix %s.\n", ifr.ifr_name, olsr_ip_prefix_to_string(&iface->cnf->ipv6_src));
611       return 0;
612     }
613     OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&buf, &iface->cnf->ipv6_multicast.v6));
614
615     /* Multicast */
616     memset(&ifs.int6_multaddr, 0, sizeof(ifs.int6_multaddr));
617     ifs.int6_multaddr.sin6_family = AF_INET6;
618     ifs.int6_multaddr.sin6_flowinfo = htonl(0);
619     ifs.int6_multaddr.sin6_scope_id = if_nametoindex(ifr.ifr_name);
620     ifs.int6_multaddr.sin6_port = htons(olsr_cnf->olsrport);
621     ifs.int6_multaddr.sin6_addr =  iface->cnf->ipv6_multicast.v6;
622
623 #ifdef __MacOSX__
624     ifs.int6_multaddr.sin6_scope_id = 0;
625 #endif
626
627     OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
628
629   }
630   /* IP version 4 */
631   else {
632     /* Get interface address (IPv4) */
633     if (iface->cnf->ipv4_src.v4.s_addr) {
634       ifs.int_addr.sin_addr = iface->cnf->ipv4_src.v4;
635     }
636     else {
637       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
638         OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
639         return 0;
640       }
641
642       ifs.int_addr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_addr);
643     }
644     /* Find netmask */
645     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
646       olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
647       return 0;
648     }
649
650     ifs.int_netmask = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_netmask);
651
652     /* Find broadcast address */
653     if (iface->cnf->ipv4_multicast.v4.s_addr) {
654       /* Specified broadcast */
655       memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, &iface->cnf->ipv4_multicast.v4, sizeof(uint32_t));
656     } else {
657       /* Autodetect */
658       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) {
659         olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
660         return 0;
661       }
662
663       ifs.int_broadaddr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr);
664     }
665
666     /* Deactivate IP spoof filter */
667     /* Disable ICMP redirects */
668     net_os_set_ifoptions(if_basename(ifr.ifr_name), &ifs);
669   }
670
671   /* Get interface index */
672
673   ifs.if_index = if_nametoindex(ifr.ifr_name);
674
675   /* Set interface metric */
676   if (iface->cnf->weight.fixed)
677     ifs.int_metric = iface->cnf->weight.value;
678   else
679     ifs.int_metric = calculate_if_metric(ifr.ifr_name);
680   OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
681
682   /* Get MTU */
683   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
684     ifs.int_mtu = OLSR_DEFAULT_MTU;
685   else
686     ifs.int_mtu = ifr.ifr_mtu;
687
688   ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
689
690   ifs.ttl_index = -32;          /* For the first 32 TC's, fish-eye is disabled */
691
692   /* Set up buffer */
693   net_add_buffer(&ifs);
694
695   OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
696
697   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
698   OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_index);
699
700   if (olsr_cnf->ip_version == AF_INET) {
701     struct ipaddr_str buf;
702     OLSR_PRINTF(1, "\tAddress:%s\n", ip4_to_string(&buf, ifs.int_addr.sin_addr));
703     OLSR_PRINTF(1, "\tNetmask:%s\n", ip4_to_string(&buf, ifs.int_netmask.sin_addr));
704     OLSR_PRINTF(1, "\tBroadcast address:%s\n", ip4_to_string(&buf, ifs.int_broadaddr.sin_addr));
705   } else {
706     struct ipaddr_str buf;
707     OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
708     OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
709   }
710
711   name_size = strlen(if_basename(ifr.ifr_name)) + 1;
712   ifs.int_name = olsr_malloc(name_size, "Interface update 3");
713   strscpy(ifs.int_name, if_basename(ifr.ifr_name), name_size);
714
715   if (olsr_cnf->ip_version == AF_INET) {
716     /* IP version 4 */
717     ifs.ip_addr.v4 = ifs.int_addr.sin_addr;
718     /*
719      *We create one socket for each interface and bind
720      *the socket to it. This to ensure that we can control
721      *on what interface the message is transmitted
722      */
723
724     ifs.olsr_socket = getsocket(BUFSPACE, &ifs);
725     ifs.send_socket = getsocket(0, &ifs);
726
727     if (ifs.olsr_socket < 0) {
728       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
729       olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
730       olsr_cnf->exit_value = EXIT_FAILURE;
731       free(ifs.int_name);
732       kill(getpid(), SIGINT);
733       return 0;
734     }
735     if (ifs.send_socket < 0) {
736       OLSR_PRINTF(1, "Warning, transmission socket could not be initialized. Abort if-up.\n");
737       close (ifs.olsr_socket);
738       free(ifs.int_name);
739       return 0;
740     }
741   } else {
742     /* IP version 6 */
743     ifs.ip_addr.v6 = ifs.int6_addr.sin6_addr;
744
745     /*
746      *We create one socket for each interface and bind
747      *the socket to it. This to ensure that we can control
748      *on what interface the message is transmitted
749      */
750
751     ifs.olsr_socket = getsocket6(BUFSPACE, &ifs);
752     ifs.send_socket = getsocket6(0, &ifs);
753
754     if (ifs.olsr_socket < 0) {
755       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
756       olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
757       olsr_cnf->exit_value = EXIT_FAILURE;
758       free(ifs.int_name);
759       kill(getpid(), SIGINT);
760       return 0;
761     }
762     if (ifs.send_socket < 0) {
763       OLSR_PRINTF(1, "Warning, transmission socket could not be initialized. Abort if-up.\n");
764       close (ifs.olsr_socket);
765       free(ifs.int_name);
766       return 0;
767     }
768
769     join_mcast(&ifs, ifs.olsr_socket);
770     join_mcast(&ifs, ifs.send_socket);
771   }
772
773   ifp = olsr_malloc(sizeof(struct interface), "Interface update 2");
774
775   iface->configured = 1;
776   iface->interf = ifp;
777
778   /* XXX bad code */
779   memcpy(ifp, &ifs, sizeof(struct interface));
780
781   /* initialize backpointer */
782   ifp->olsr_if = iface;
783
784   ifp->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
785   if (olsr_cnf->max_jitter == 0) {
786     /* max_jitter determines the max time to store to-be-send-messages, correlated with random() */
787     olsr_cnf->max_jitter =
788       ifp->immediate_send_tc ? iface->cnf->tc_params.emission_interval : iface->cnf->hello_params.emission_interval;
789   }
790
791   ifp->gen_properties = NULL;
792   ifp->int_next = ifnet;
793   ifnet = ifp;
794
795   set_buffer_timer(ifp);
796
797   /* Register socket */
798   add_olsr_socket(ifp->olsr_socket, &olsr_input, NULL, NULL, SP_PR_READ);
799   add_olsr_socket(ifp->send_socket, &olsr_input, NULL, NULL, SP_PR_READ);
800
801 #ifdef linux
802   /* Set TOS */
803
804   if (setsockopt(ifp->olsr_socket, SOL_SOCKET, SO_PRIORITY, (char *)&precedence, sizeof(precedence)) < 0) {
805     perror("setsockopt(SO_PRIORITY)");
806     olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
807   }
808   if (setsockopt(ifp->olsr_socket, SOL_IP, IP_TOS, (char *)&tos_bits, sizeof(tos_bits)) < 0) {
809     perror("setsockopt(IP_TOS)");
810     olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
811   }
812 #endif
813
814   /*
815    *Initialize sequencenumber as a random 16bit value
816    */
817   ifp->olsr_seqnum = random() & 0xFFFF;
818
819   /*
820    * Set main address if this is the only interface
821    */
822   memset(&null_addr, 0, olsr_cnf->ipsize);
823   if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
824     struct ipaddr_str buf;
825     olsr_cnf->main_addr = ifp->ip_addr;
826     olsr_cnf->unicast_src_ip = ifp->ip_addr;
827     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
828     olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
829   }
830
831   /*
832    * Register functions for periodic message generation
833    */
834   ifp->hello_gen_timer =
835     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
836                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
837   ifp->tc_gen_timer =
838     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
839                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
840   ifp->mid_gen_timer =
841     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
842                      mid_gen_timer_cookie);
843   ifp->hna_gen_timer =
844     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
845                      hna_gen_timer_cookie);
846
847   /* Recalculate max topology hold time */
848   if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval) {
849     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
850   }
851   ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
852   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
853   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
854   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
855   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
856
857   ifp->mode = iface->cnf->mode;
858
859   /*
860    *Call possible ifchange functions registered by plugins
861    */
862   olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_ADD);
863
864   return 1;
865 }
866
867 /*
868  * Local Variables:
869  * c-basic-offset: 2
870  * indent-tabs-mode: nil
871  * End:
872  */