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