all: use the getInterfaceLinkState function
[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 __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
43 #define ifr_netmask ifr_addr
44 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
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 #include "olsr_random.h"
61
62 #include <assert.h>
63 #include <signal.h>
64 #include <sys/types.h>
65 #include <net/if.h>
66 #include <net/if_arp.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/ip.h>
69 #include <arpa/inet.h>
70 #include <netdb.h>
71 #include <unistd.h>
72 #if defined(__linux__) && !defined(__ANDROID__)
73 #include <linux/ethtool.h>
74 #include <linux/sockios.h>
75 #endif /* defined(__linux__) && !defined(__ANDROID__) */
76
77 /**
78  * Fix bug in GLIBC, see https://bugzilla.redhat.com/show_bug.cgi?id=635260
79  */
80 #ifdef IPTOS_CLASS
81 #undef IPTOS_CLASS
82 #endif /* IPTOS_CLASS */
83 #define IPTOS_CLASS(class)    ((class) & IPTOS_CLASS_MASK)
84
85 #define BUFSPACE  (127*1024)    /* max. input buffer size to request */
86
87 static const uint8_t  zero_v6[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
88
89 void
90 check_interface_updates(void *foo __attribute__ ((unused)))
91 {
92   struct olsr_if *tmp_if;
93
94 #ifdef DEBUG
95   OLSR_PRINTF(3, "Checking for updates in the interface set\n");
96 #endif /* DEBUG */
97
98   for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
99     if (tmp_if->host_emul)
100       continue;
101
102     if (olsr_cnf->host_emul)    /* XXX: TEMPORARY! */
103       continue;
104
105     if (!tmp_if->cnf->autodetect_chg) {
106 #ifdef DEBUG
107       /* Don't check this interface */
108       OLSR_PRINTF(3, "Not checking interface %s\n", tmp_if->name);
109 #endif /* DEBUG */
110       continue;
111     }
112
113     if (tmp_if->configured) {
114       chk_if_changed(tmp_if);
115     } else {
116       chk_if_up(tmp_if, 3);
117     }
118   }
119
120   return;
121 }
122
123 /**
124  * Checks if an initialized interface is changed
125  * that is if it has been set down or the address
126  * has been changed.
127  *
128  *@param iface the olsr_if struct describing the interface
129  *@return 1 when the interface changed, 0 if it did not change
130  */
131 int
132 chk_if_changed(struct olsr_if *iface)
133 {
134   struct interface_olsr *ifp;
135   struct ifreq ifr;
136   struct sockaddr_in6 tmp_saddr6;
137   int if_changes;
138   if_changes = 0;
139
140 #ifdef DEBUG
141   OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
142 #endif /* DEBUG */
143
144   if (iface->host_emul)
145     return -1;
146
147   ifp = iface->interf;
148
149   if (ifp == NULL) {
150     /* Should not happen */
151     iface->configured = 0;
152     return 0;
153   }
154
155   memset(&ifr, 0, sizeof(struct ifreq));
156   strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
157
158   /* Get flags (and check if interface exists) */
159   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
160     OLSR_PRINTF(3, "No such interface: %s\n", iface->name);
161     goto remove_interface;
162   }
163
164   ifp->int_flags = ifr.ifr_flags;
165
166   /*
167    * First check if the interface is set DOWN
168    */
169
170   if ((getInterfaceLinkState(iface->name) == LINKSTATE_DOWN) || (ifp->int_flags & IFF_UP) == 0) {
171     OLSR_PRINTF(1, "\tInterface %s not up and running - removing it...\n", iface->name);
172     goto remove_interface;
173   }
174
175   /*
176    * We do all the interface type checks over.
177    * This is because the interface might be a PCMCIA card. Therefore
178    * It might not be the same physical interface as we configured earlier.
179    */
180
181   /* Check broadcast */
182   if ((olsr_cnf->ip_version == AF_INET) && !iface->cnf->ipv4_multicast.v4.s_addr &&     /* Skip if fixed bcast */
183       (!(ifp->int_flags & IFF_BROADCAST))) {
184     OLSR_PRINTF(3, "\tNo broadcast - removing\n");
185     goto remove_interface;
186   }
187
188   if (ifp->int_flags & IFF_LOOPBACK) {
189     OLSR_PRINTF(3, "\tThis is a loopback interface - removing it...\n");
190     goto remove_interface;
191   }
192
193   ifp->is_hcif = false;
194
195   /* trying to detect if interface is wireless. */
196   ifp->is_wireless = check_wireless_interface(ifr.ifr_name);
197
198   /* Set interface metric */
199   if (iface->cnf->weight.fixed)
200     ifp->int_metric = iface->cnf->weight.value;
201   else
202     ifp->int_metric = calculate_if_metric(ifr.ifr_name);
203
204   /* Get MTU */
205   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
206     ifp->int_mtu = 0;
207   else {
208     ifr.ifr_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
209
210     if (ifp->int_mtu != ifr.ifr_mtu) {
211       ifp->int_mtu = ifr.ifr_mtu;
212       /* Create new outputbuffer */
213       net_remove_buffer(ifp);   /* Remove old */
214       net_add_buffer(ifp);
215     }
216   }
217
218   /* Get interface index */
219   ifp->if_index = if_nametoindex(ifr.ifr_name);
220
221   /*
222    * Now check if the IP has changed
223    */
224
225   /* IP version 6 */
226   if (olsr_cnf->ip_version == AF_INET6) {
227     struct ipaddr_str buf;
228     /* Get dst interface address */
229
230     if (0 == get_ipv6_address(iface->name, &tmp_saddr6, (iface->cnf->ipv6_src.prefix_len == 0) ? NULL : (&iface->cnf->ipv6_src))) {
231       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));
232       goto remove_interface;
233     }
234
235 #ifdef DEBUG
236     OLSR_PRINTF(3, "\tAddress: %s\n", ip6_to_string(&buf, &iface->cnf->ipv6_multicast.v6));
237 #endif /* DEBUG */
238
239     if (memcmp(&tmp_saddr6.sin6_addr, &ifp->int6_addr.sin6_addr, olsr_cnf->ipsize) != 0) {
240       OLSR_PRINTF(1, "New IP address for %s:\n", ifr.ifr_name);
241       OLSR_PRINTF(1, "\tOld: %s\n", ip6_to_string(&buf, &ifp->int6_addr.sin6_addr));
242       OLSR_PRINTF(1, "\tNew: %s\n", ip6_to_string(&buf, &tmp_saddr6.sin6_addr));
243
244       /* Update address */
245       memcpy(&ifp->int6_addr.sin6_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
246       memcpy(&ifp->ip_addr, &tmp_saddr6.sin6_addr, olsr_cnf->ipsize);
247
248       olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_UPDATE);
249
250       /* we have to make sure that olsrd uses the new source address of this interface */
251       olsr_remove_interface(iface); /* so we remove the interface completely */
252       chk_if_up(iface,3); /* and create it again to get new sockets,..*/
253     }
254     return 0;
255
256   } else
257     /* IP version 4 */
258   {
259     struct ipaddr_str buf;
260     /* Check interface address (IPv4) */
261     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
262       OLSR_PRINTF(1, "\tCould not get address of interface - removing it\n");
263       goto remove_interface;
264     }
265 #ifdef DEBUG
266     OLSR_PRINTF(3, "\tAddress:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
267 #endif /* DEBUG */
268
269     if (memcmp
270         (&((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,
271          olsr_cnf->ipsize) != 0) {
272       /* New address */
273       OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name);
274       OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_addr.sin_addr));
275       OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_addr));
276
277       ifp->int_addr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_addr);
278       memcpy(&ifp->ip_addr, &((struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_addr))->sin_addr.s_addr, olsr_cnf->ipsize);
279
280       /* we have to make sure that olsrd uses the new source address of this interface */
281       olsr_remove_interface(iface); /* so we remove the interface completely */
282       chk_if_up(iface,3); /* and create it again to get new sockets,..*/
283       return 0;
284     }
285
286     /* Check netmask */
287     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
288       olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
289       goto remove_interface;
290     }
291 #ifdef DEBUG
292     OLSR_PRINTF(3, "\tNetmask:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
293 #endif /* DEBUG */
294
295     if (memcmp
296         (&((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,
297          olsr_cnf->ipsize) != 0) {
298       /* New address */
299       OLSR_PRINTF(1, "IPv4 netmask changed for %s\n", ifr.ifr_name);
300       OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_netmask.sin_addr));
301       OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_netmask));
302
303       ifp->int_netmask = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_netmask);
304
305       if_changes = 1;
306     }
307
308     if (!iface->cnf->ipv4_multicast.v4.s_addr) {
309       struct sockaddr_in *ptr;
310
311       /* Check broadcast address */
312       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) {
313         olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
314         goto remove_interface;
315       }
316
317       ptr = (struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr);
318       if (ptr->sin_addr.s_addr == 0) {
319         memset(&ptr->sin_addr, 255, 4);
320       }
321
322 #ifdef DEBUG
323       OLSR_PRINTF(3, "\tBroadcast address:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
324 #endif /* DEBUG */
325
326       if (ifp->int_broadaddr.sin_addr.s_addr != ptr->sin_addr.s_addr) {
327         /* New address */
328         OLSR_PRINTF(1, "IPv4 broadcast changed for %s\n", ifr.ifr_name);
329         OLSR_PRINTF(1, "\tOld:%s\n", ip4_to_string(&buf, ifp->int_broadaddr.sin_addr));
330         OLSR_PRINTF(1, "\tNew:%s\n", sockaddr4_to_string(&buf, &ifr.ifr_broadaddr));
331
332         ifp->int_broadaddr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr);
333         if_changes = 1;
334       }
335     }
336   }
337
338   if (if_changes)
339     olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_UPDATE);
340
341   return if_changes;
342
343 remove_interface:
344
345   olsr_remove_interface(iface);
346   return 0;
347 }
348
349 /**
350  * Initializes the special interface used in
351  * host-client emulation
352  */
353 int
354 add_hemu_if(struct olsr_if *iface)
355 {
356   struct interface_olsr *ifp;
357   union olsr_ip_addr null_addr;
358   uint32_t addr[4];
359   struct ipaddr_str buf;
360   size_t name_size;
361
362   if (!iface->host_emul)
363     return -1;
364
365   ifp = olsr_malloc(sizeof(struct interface_olsr), "Interface update 2");
366
367   memset(ifp, 0, sizeof(struct interface_olsr));
368
369   /* initialize backpointer */
370   ifp->olsr_if = iface;
371
372   iface->configured = true;
373   iface->interf = ifp;
374
375   name_size = strlen("hcif01") + 1;
376   ifp->is_hcif = true;
377   ifp->int_name = olsr_malloc(name_size, "Interface update 3");
378   ifp->int_metric = 0;
379
380   strscpy(ifp->int_name, "hcif01", name_size);
381
382   OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
383
384   OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
385
386   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
387
388   ifp->int_next = ifnet;
389   ifnet = ifp;
390
391   memset(&null_addr, 0, olsr_cnf->ipsize);
392   if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
393     olsr_cnf->main_addr = iface->hemu_ip;
394     olsr_cnf->unicast_src_ip = iface->hemu_ip;
395     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
396     olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
397   }
398
399   ifp->int_mtu = OLSR_DEFAULT_MTU;
400
401   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
402
403   /* Set up buffer */
404   net_add_buffer(ifp);
405
406   if (olsr_cnf->ip_version == AF_INET) {
407     struct sockaddr_in sin;
408
409     memset(&sin, 0, sizeof(sin));
410
411     sin.sin_family = AF_INET;
412     sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
413     sin.sin_port = htons(10150);
414
415     /* IP version 4 */
416     ifp->ip_addr.v4 = iface->hemu_ip.v4;
417
418     memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
419
420     /*
421      *We create one socket for each interface and bind
422      *the socket to it. This to ensure that we can control
423      *on what interface the message is transmitted
424      */
425
426     ifp->olsr_socket = gethemusocket(&sin);
427
428     if (ifp->olsr_socket < 0) {
429       olsr_exit("Could not initialize socket", EXIT_FAILURE);
430     }
431
432   } else {
433     /* IP version 6 */
434     memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
435   }
436
437   /* Send IP as first 4/16 bytes on socket */
438   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
439   addr[0] = htonl(addr[0]);
440   addr[1] = htonl(addr[1]);
441   addr[2] = htonl(addr[2]);
442   addr[3] = htonl(addr[3]);
443
444   if (send(ifp->olsr_socket, addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize) {
445     fprintf(stderr, "Error sending IP!");
446   }
447
448   /* Register socket */
449   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu, NULL, NULL, SP_PR_READ);
450
451   /*
452    * Register functions for periodic message generation
453    */
454
455   ifp->hello_gen_timer =
456     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
457                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
458   ifp->tc_gen_timer =
459     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
460                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
461   ifp->mid_gen_timer =
462     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
463                      mid_gen_timer_cookie);
464   ifp->hna_gen_timer =
465     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
466                      hna_gen_timer_cookie);
467
468   /* Recalculate max topology hold time */
469   if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
470     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
471
472   ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
473   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
474   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
475   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
476   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
477   ifp->valtimes.hna_reltime = me_to_reltime(ifp->valtimes.hna);
478
479   ifp->mode = iface->cnf->mode;
480
481   return 1;
482 }
483
484 static char basenamestr[32];
485 static const char *if_basename(const char *name);
486 static const char *
487 if_basename(const char *name)
488 {
489   char *p = strchr(name, ':');
490   if (NULL == p || p - name >= (int)(sizeof(basenamestr) / sizeof(basenamestr[0]) - 1)) {
491     return name;
492   }
493   memcpy(basenamestr, name, p - name);
494   basenamestr[p - name] = 0;
495   return basenamestr;
496 }
497
498 /**
499  * Initializes a interface described by iface,
500  * if it is set up and is of the correct type.
501  *
502  *@param iface the olsr_if struct describing the interface
503  *@param debuglvl the debug level
504  *@return -1 when emulated (iface->host_emul), 0 on error, 1 on succes
505  */
506 int
507 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
508 {
509   struct interface_olsr ifs, *ifp;
510   struct ifreq ifr;
511   union olsr_ip_addr null_addr;
512   size_t name_size;
513 #ifdef __linux__
514   int precedence = IPTOS_PREC(olsr_cnf->tos);
515   int tos_bits = olsr_cnf->tos;
516 #endif /* __linux__ */
517
518   if (iface->host_emul)
519     return -1;
520
521   memset(&ifr, 0, sizeof(struct ifreq));
522   memset(&ifs, 0, sizeof(struct interface_olsr));
523   strscpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
524
525   OLSR_PRINTF(debuglvl, "Checking %s:\n", ifr.ifr_name);
526
527   /* Get flags (and check if interface exists) */
528   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
529     OLSR_PRINTF(debuglvl, "\tNo such interface!\n");
530     return 0;
531   }
532
533   ifs.int_flags = ifr.ifr_flags;
534
535   if ((getInterfaceLinkState(iface->name) == LINKSTATE_DOWN) || ((ifs.int_flags & IFF_UP) == 0)) {
536     OLSR_PRINTF(debuglvl, "\tInterface not up & running - skipping it...\n");
537     return 0;
538   }
539
540   /* Check broadcast */
541   if ((olsr_cnf->ip_version == AF_INET) && !iface->cnf->ipv4_multicast.v4.s_addr &&     /* Skip if fixed bcast */
542       (!(ifs.int_flags & IFF_BROADCAST))) {
543     OLSR_PRINTF(debuglvl, "\tNo broadcast - skipping\n");
544     return 0;
545   }
546
547   if (ifs.int_flags & IFF_LOOPBACK) {
548     OLSR_PRINTF(debuglvl, "\tThis is a loopback interface - skipping it...\n");
549     return 0;
550   }
551
552   ifs.is_hcif = false;
553
554   /* trying to detect if interface is wireless. */
555   ifs.is_wireless = check_wireless_interface(ifr.ifr_name);
556
557   if (ifs.is_wireless)
558     OLSR_PRINTF(debuglvl, "\tWireless interface detected\n");
559   else
560     OLSR_PRINTF(debuglvl, "\tNot a wireless interface\n");
561
562   /* IP version 6 */
563   if (olsr_cnf->ip_version == AF_INET6) {
564     /* Get interface address */
565     struct ipaddr_str buf;
566
567     if (0 == get_ipv6_address(iface->name, &ifs.int6_addr, (iface->cnf->ipv6_src.prefix_len == 0) ? NULL : (&iface->cnf->ipv6_src))) {
568       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));
569       return 0;
570     }
571     OLSR_PRINTF(debuglvl, "\tAddress: %s\n", ip6_to_string(&buf, &iface->cnf->ipv6_multicast.v6));
572
573     /* Multicast */
574     memset(&ifs.int6_multaddr, 0, sizeof(ifs.int6_multaddr));
575     ifs.int6_multaddr.sin6_family = AF_INET6;
576     ifs.int6_multaddr.sin6_flowinfo = htonl(0);
577     ifs.int6_multaddr.sin6_scope_id = if_nametoindex(ifr.ifr_name);
578     ifs.int6_multaddr.sin6_port = htons(olsr_cnf->olsrport);
579     ifs.int6_multaddr.sin6_addr =  iface->cnf->ipv6_multicast.v6;
580
581     if (memcmp(zero_v6, &ifs.int6_multaddr.sin6_addr, 16) == 0) {
582       memset(&ifs.int6_multaddr.sin6_addr, 255, 16);
583     }
584
585 #ifdef __APPLE__
586     ifs.int6_multaddr.sin6_scope_id = 0;
587 #endif /* __APPLE__ */
588
589     OLSR_PRINTF(debuglvl, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
590
591   }
592   /* IP version 4 */
593   else {
594     /* Get interface address (IPv4) */
595     if (iface->cnf->ipv4_src.v4.s_addr) {
596       ifs.int_addr.sin_addr = iface->cnf->ipv4_src.v4;
597     }
598     else {
599       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
600         OLSR_PRINTF(debuglvl, "\tCould not get address of interface - skipping it\n");
601         return 0;
602       }
603
604       ifs.int_addr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_addr);
605     }
606     /* Find netmask */
607     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
608       olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get netmask)", ifr.ifr_name);
609       return 0;
610     }
611
612     ifs.int_netmask = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_netmask);
613
614     /* Find broadcast address */
615     if (iface->cnf->ipv4_multicast.v4.s_addr) {
616       /* Specified broadcast */
617       memcpy(&((struct sockaddr_in *)&ifs.int_broadaddr)->sin_addr.s_addr, &iface->cnf->ipv4_multicast.v4, sizeof(uint32_t));
618     } else {
619       /* Autodetect */
620       if (ioctl(olsr_cnf->ioctl_s, SIOCGIFBRDADDR, &ifr) < 0) {
621         olsr_syslog(OLSR_LOG_ERR, "%s: ioctl (get broadaddr)", ifr.ifr_name);
622         return 0;
623       }
624
625       ifs.int_broadaddr = *(struct sockaddr_in *)ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr);
626       if (ifs.int_broadaddr.sin_addr.s_addr == 0) {
627         memset(&ifs.int_broadaddr.sin_addr, 255, 4);
628       }
629     }
630
631     /* Deactivate IP spoof filter */
632     /* Disable ICMP redirects */
633     net_os_set_ifoptions(if_basename(ifr.ifr_name), &ifs);
634   }
635
636   /* Get interface index */
637
638   ifs.if_index = if_nametoindex(ifr.ifr_name);
639
640   /* Set interface metric */
641   if (iface->cnf->weight.fixed)
642     ifs.int_metric = iface->cnf->weight.value;
643   else
644     ifs.int_metric = calculate_if_metric(ifr.ifr_name);
645   OLSR_PRINTF(1, "\tMetric: %d\n", ifs.int_metric);
646
647   /* Get MTU */
648   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMTU, &ifr) < 0)
649     ifs.int_mtu = OLSR_DEFAULT_MTU;
650   else
651     ifs.int_mtu = ifr.ifr_mtu;
652
653   ifs.int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
654
655   ifs.ttl_index = -32;          /* For the first 32 TC's, fish-eye is disabled */
656
657   OLSR_PRINTF(1, "\tMTU - IPhdr: %d\n", ifs.int_mtu);
658
659   olsr_syslog(OLSR_LOG_INFO, "Adding interface %s\n", iface->name);
660   OLSR_PRINTF(1, "\tIndex %d\n", ifs.if_index);
661
662   if (olsr_cnf->ip_version == AF_INET) {
663     struct ipaddr_str buf;
664     OLSR_PRINTF(1, "\tAddress:%s\n", ip4_to_string(&buf, ifs.int_addr.sin_addr));
665     OLSR_PRINTF(1, "\tNetmask:%s\n", ip4_to_string(&buf, ifs.int_netmask.sin_addr));
666     OLSR_PRINTF(1, "\tBroadcast address:%s\n", ip4_to_string(&buf, ifs.int_broadaddr.sin_addr));
667   } else {
668     struct ipaddr_str buf;
669     OLSR_PRINTF(1, "\tAddress: %s\n", ip6_to_string(&buf, &ifs.int6_addr.sin6_addr));
670     OLSR_PRINTF(1, "\tMulticast: %s\n", ip6_to_string(&buf, &ifs.int6_multaddr.sin6_addr));
671   }
672
673   name_size = strlen(if_basename(ifr.ifr_name)) + 1;
674   ifs.int_name = olsr_malloc(name_size, "Interface update 3");
675   strscpy(ifs.int_name, if_basename(ifr.ifr_name), name_size);
676
677   if (olsr_cnf->ip_version == AF_INET) {
678     /* IP version 4 */
679     ifs.ip_addr.v4 = ifs.int_addr.sin_addr;
680     /*
681      *We create one socket for each interface and bind
682      *the socket to it. This to ensure that we can control
683      *on what interface the message is transmitted
684      */
685
686     ifs.olsr_socket = getsocket(BUFSPACE, &ifs);
687     ifs.send_socket = getsocket(0, &ifs);
688
689     if (ifs.olsr_socket < 0) {
690       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
691       olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
692       olsr_cnf->exit_value = EXIT_FAILURE;
693       free(ifs.int_name);
694       kill(getpid(), SIGINT);
695       return 0;
696     }
697     if (ifs.send_socket < 0) {
698       OLSR_PRINTF(1, "Warning, transmission socket could not be initialized. Abort if-up.\n");
699       close (ifs.olsr_socket);
700       free(ifs.int_name);
701       return 0;
702     }
703   } else {
704     /* IP version 6 */
705     ifs.ip_addr.v6 = ifs.int6_addr.sin6_addr;
706
707     /*
708      *We create one socket for each interface and bind
709      *the socket to it. This to ensure that we can control
710      *on what interface the message is transmitted
711      */
712
713     ifs.olsr_socket = getsocket6(BUFSPACE, &ifs);
714     ifs.send_socket = getsocket6(0, &ifs);
715
716     if (ifs.olsr_socket < 0) {
717       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
718       olsr_syslog(OLSR_LOG_ERR, "Could not initialize socket... exiting!\n\n");
719       olsr_cnf->exit_value = EXIT_FAILURE;
720       free(ifs.int_name);
721       kill(getpid(), SIGINT);
722       return 0;
723     }
724     if (ifs.send_socket < 0) {
725       OLSR_PRINTF(1, "Warning, transmission socket could not be initialized. Abort if-up.\n");
726       close (ifs.olsr_socket);
727       free(ifs.int_name);
728       return 0;
729     }
730
731     join_mcast(&ifs, ifs.olsr_socket);
732     join_mcast(&ifs, ifs.send_socket);
733   }
734
735   ifp = olsr_malloc(sizeof(struct interface_olsr), "Interface update 2");
736
737   iface->configured = 1;
738   iface->interf = ifp;
739
740   /* XXX bad code */
741   memcpy(ifp, &ifs, sizeof(struct interface_olsr));
742
743   /* initialize backpointer */
744   ifp->olsr_if = iface;
745
746   ifp->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
747   if (olsr_cnf->max_jitter == 0) {
748     /* max_jitter determines the max time to store to-be-send-messages, correlated with random() */
749     olsr_cnf->max_jitter =
750       ifp->immediate_send_tc ? iface->cnf->tc_params.emission_interval : iface->cnf->hello_params.emission_interval;
751   }
752
753   ifp->gen_properties = NULL;
754   ifp->int_next = ifnet;
755   ifnet = ifp;
756
757   set_buffer_timer(ifp);
758
759   /* Register socket */
760   add_olsr_socket(ifp->olsr_socket, &olsr_input, NULL, NULL, SP_PR_READ);
761   add_olsr_socket(ifp->send_socket, &olsr_input, NULL, NULL, SP_PR_READ);
762
763 #ifdef __linux__
764   /* Set TOS */
765
766   if (setsockopt(ifp->send_socket, SOL_SOCKET, SO_PRIORITY, (char *)&precedence, sizeof(precedence)) < 0) {
767     perror("setsockopt(SO_PRIORITY)");
768     olsr_syslog(OLSR_LOG_ERR, "OLSRD: setsockopt(SO_PRIORITY) error %m");
769   }
770   if (olsr_cnf->ip_version == AF_INET) {
771     if (setsockopt(ifp->send_socket, IPPROTO_IP, IP_TOS, (char *)&tos_bits, sizeof(tos_bits)) < 0) {
772       perror("setsockopt(IP_TOS)");
773       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IP_TOS) error %m");
774     }
775   } else {
776     /* IP version 6 */
777 #ifdef IPV6_TCLASS
778     if (setsockopt(ifp->send_socket, IPPROTO_IPV6, IPV6_TCLASS, (char *)&tos_bits, sizeof(tos_bits)) < 0) {
779       perror("setsockopt(IPV6_TCLASS)");
780       olsr_syslog(OLSR_LOG_ERR, "setsockopt(IPV6_TCLASS) error %m");
781     }
782 #endif
783   }
784 #endif /* __linux__ */
785
786   /*
787    *Initialize sequencenumber as a random 16bit value
788    */
789   ifp->olsr_seqnum = olsr_random() & 0xFFFF;
790
791   /*
792    * Set main address if this is the only interface
793    */
794   memset(&null_addr, 0, olsr_cnf->ipsize);
795   if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
796     struct ipaddr_str buf;
797     olsr_cnf->main_addr = ifp->ip_addr;
798     olsr_cnf->unicast_src_ip = ifp->ip_addr;
799     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
800     olsr_syslog(OLSR_LOG_INFO, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
801   }
802
803   /*
804    * Register functions for periodic message generation
805    */
806   ifp->hello_gen_timer =
807     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
808                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
809   ifp->tc_gen_timer =
810     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
811                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
812   ifp->mid_gen_timer =
813     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
814                      mid_gen_timer_cookie);
815   ifp->hna_gen_timer =
816     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
817                      hna_gen_timer_cookie);
818
819   /* Recalculate max topology hold time */
820   if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval) {
821     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
822   }
823   ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
824   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
825   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
826   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
827   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
828   ifp->valtimes.hna_reltime = me_to_reltime(ifp->valtimes.hna);
829
830   ifp->mode = iface->cnf->mode;
831
832   /* Set up buffer */
833   net_add_buffer(ifp);
834
835   /*
836    *Call possible ifchange functions registered by plugins
837    */
838   olsr_trigger_ifchange(ifp->if_index, ifp, IFCHG_IF_ADD);
839
840   return 1;
841 }
842
843 #if defined(__linux__) && !defined(__ANDROID__)
844 LinkState getInterfaceLinkState(const char * iface) {
845   LinkState r = LINKSTATE_UNKNOWN;
846   int fd;
847   struct ethtool_value edata;
848   struct ifreq ifr;
849
850   if (!iface) {
851     return r;
852   }
853
854   memset(&ifr, 0, sizeof(ifr));
855
856   fd = socket(AF_INET, SOCK_DGRAM, 0);
857   if (fd < 0) {
858     return r;
859   }
860
861   edata.cmd = ETHTOOL_GLINK;
862   strcpy(ifr.ifr_name, iface);
863   ifr.ifr_data = (caddr_t) &edata;
864   errno = 0;
865   if (!ioctl(fd, SIOCETHTOOL, &ifr)) {
866     /* ioctl success */
867     r = edata.data ? LINKSTATE_UP : LINKSTATE_DOWN;
868   } else if (errno == EOPNOTSUPP) {
869     /* no kernel support */
870     r = LINKSTATE_UNKNOWN;
871   } else {
872     /* other error */
873     r = LINKSTATE_UNKNOWN;
874   }
875
876   close(fd);
877   return r;
878 }
879 #endif /* defined(__linux__) && !defined(__ANDROID__) */
880
881 /*
882  * Local Variables:
883  * c-basic-offset: 2
884  * indent-tabs-mode: nil
885  * End:
886  */