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