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