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