Removed redundant header inclusion
[olsrd.git] / src / win32 / ifnet.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: ifnet.c,v 1.25 2005/05/26 21:04:22 kattemat Exp $
40  */
41
42 #include "interfaces.h"
43 #include "olsr.h"
44 #include "parser.h"
45 #include "socket_parser.h"
46 #include "defs.h"
47 #include "net_os.h"
48 #include "ifnet.h"
49 #include "generate_msg.h"
50 #include "scheduler.h"
51 #include "mantissa.h"
52 #include "lq_packet.h"
53
54 #include <iphlpapi.h>
55 #include <iprtrmib.h>
56
57 struct InterfaceInfo
58 {
59   unsigned int Index;
60   int Mtu;
61   unsigned int Addr;
62   unsigned int Mask;
63   unsigned int Broad;
64   char Guid[39];
65 };
66
67 void WinSockPError(char *);
68 char *StrError(unsigned int ErrNo);
69 int inet_pton(int af, char *src, void *dst);
70
71 void ListInterfaces(void);
72 int GetIntInfo(struct InterfaceInfo *Info, char *Name);
73 void RemoveInterface(struct olsr_if *IntConf);
74
75 #define MAX_INTERFACES 25
76
77 int __stdcall SignalHandler(unsigned long Signal);
78
79 static unsigned long __stdcall SignalHandlerWrapper(void *Dummy)
80 {
81   SignalHandler(0);
82   return 0;
83 }
84
85 static void CallSignalHandler(void)
86 {
87   unsigned long ThreadId;
88
89   CreateThread(NULL, 0, SignalHandlerWrapper, NULL, 0, &ThreadId);
90 }
91
92 static void MiniIndexToIntName(char *String, int MiniIndex)
93 {
94   char *HexDigits = "0123456789abcdef";
95
96   String[0] = 'i';
97   String[1] = 'f';
98
99   String[2] = HexDigits[(MiniIndex >> 4) & 15];
100   String[3] = HexDigits[MiniIndex & 15];
101
102   String[4] = 0;
103 }
104
105 static int IntNameToMiniIndex(int *MiniIndex, char *String)
106 {
107   char *HexDigits = "0123456789abcdef";
108   int i, k;
109   char ch;
110
111   if ((String[0] != 'i' && String[0] != 'I') ||
112       (String[1] != 'f' && String[1] != 'F'))
113     return -1;
114
115   *MiniIndex = 0;
116
117   for (i = 2; i < 4; i++)
118   {
119     ch = String[i];
120
121     if (ch >= 'A' && ch <= 'F')
122       ch += 32;
123
124     for (k = 0; k < 16 && ch != HexDigits[k]; k++);
125
126     if (k == 16)
127       return -1;
128
129     *MiniIndex = (*MiniIndex << 4) | k;
130   }
131
132   return 0;
133 }
134
135 int GetIntInfo(struct InterfaceInfo *Info, char *Name)
136 {
137   int MiniIndex;
138   unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4];
139   MIB_IFTABLE *IfTable;
140   unsigned long BuffLen;
141   unsigned long Res;
142   int TabIdx;
143   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
144
145   if (olsr_cnf->ip_version == AF_INET6)
146   {
147     fprintf(stderr, "IPv6 not supported by GetIntInfo()!\n");
148     return -1;
149   }
150
151   if (IntNameToMiniIndex(&MiniIndex, Name) < 0)
152   {
153     fprintf(stderr, "No such interface: %s!\n", Name);
154     return -1;
155   }
156
157   IfTable = (MIB_IFTABLE *)Buff;
158
159   BuffLen = sizeof (Buff);
160
161   Res = GetIfTable(IfTable, &BuffLen, FALSE);
162
163   if (Res != NO_ERROR)
164   {
165     fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
166     return -1;
167   }
168
169   for (TabIdx = 0; TabIdx < (int)IfTable->dwNumEntries; TabIdx++)
170   {
171     OLSR_PRINTF(5, "Index = %08x\n", (int)IfTable->table[TabIdx].dwIndex);
172
173     if ((int)(IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
174       break;
175   }
176
177   if (TabIdx == (int)IfTable->dwNumEntries)
178   {
179     fprintf(stderr, "No such interface: %s!\n", Name);
180     return -1;
181   }
182     
183   Info->Index = IfTable->table[TabIdx].dwIndex;
184   Info->Mtu = (int)IfTable->table[TabIdx].dwMtu;
185
186   BuffLen = sizeof (AdInfo);
187
188   Res = GetAdaptersInfo(AdInfo, &BuffLen);
189
190   if (Res != NO_ERROR)
191   {
192     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(),
193             StrError(Res));
194     return -1;
195   }
196
197   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
198   {
199     OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
200
201     if ((int)(Walker->Index & 255) == MiniIndex)
202       break;
203   }
204
205   if (Walker == NULL)
206   {
207     fprintf(stderr, "No such interface: %s!\n", Name);
208     return -1;
209   }
210
211   inet_pton(AF_INET, Walker->IpAddressList.IpAddress.String, &Info->Addr);
212   inet_pton(AF_INET, Walker->IpAddressList.IpMask.String, &Info->Mask);
213
214   Info->Broad = Info->Addr | ~Info->Mask;
215
216   strcpy(Info->Guid, Walker->AdapterName);
217
218   if ((IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED &&
219       IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL) ||
220       Info->Addr == 0)
221   {
222     OLSR_PRINTF(3, "Interface %s not up!\n", Name);
223     return -1;
224   }
225
226   return 0;
227 }
228
229 #if !defined OID_802_11_CONFIGURATION
230 #define OID_802_11_CONFIGURATION 0x0d010211
231 #endif
232
233 #if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS
234 #define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
235 #endif
236
237 static int IsWireless(char *IntName)
238 {
239 #if !defined WINCE
240   struct InterfaceInfo Info;
241   char DevName[43];
242   HANDLE DevHand;
243   unsigned int ErrNo;
244   unsigned int Oid;
245   unsigned char OutBuff[100];
246   unsigned long OutBytes;
247
248   if (GetIntInfo(&Info, IntName) < 0)
249     return -1;
250
251   DevName[0] = '\\';
252   DevName[1] = '\\';
253   DevName[2] = '.';
254   DevName[3] = '\\';
255
256   strcpy(DevName + 4, Info.Guid);
257
258   OLSR_PRINTF(5, "Checking whether interface %s is wireless.\n", DevName);
259
260   DevHand = CreateFile(DevName, GENERIC_READ,
261                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
262                        FILE_ATTRIBUTE_NORMAL, NULL);
263
264   if (DevHand == INVALID_HANDLE_VALUE)
265   {
266     ErrNo = GetLastError();
267
268     OLSR_PRINTF(5, "CreateFile() = %08x, %s\n", ErrNo, StrError(ErrNo));
269     return -1;
270   }
271
272   Oid = OID_802_11_CONFIGURATION;
273
274   if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS,
275                        &Oid, sizeof (Oid),
276                        OutBuff, sizeof (OutBuff),
277                        &OutBytes, NULL))
278   {
279     ErrNo = GetLastError();
280
281     CloseHandle(DevHand);
282
283     if (ErrNo == ERROR_GEN_FAILURE)
284     {
285       OLSR_PRINTF(5, "OID not supported. Device probably not wireless.\n")
286       return 0;
287     }
288
289     OLSR_PRINTF(5, "DeviceIoControl() = %08x, %s\n", ErrNo, StrError(ErrNo))
290     return -1;
291   }
292
293   CloseHandle(DevHand);
294 #endif
295   return 1;
296 }
297
298 void ListInterfaces(void)
299 {
300   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
301   unsigned long AdInfoLen;
302   char IntName[5];
303   IP_ADDR_STRING *Walker2;
304   unsigned long Res;
305   int IsWlan;
306   
307   if (olsr_cnf->ip_version == AF_INET6)
308   {
309     fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n");
310     return;
311   }
312
313   AdInfoLen = sizeof (AdInfo);
314
315   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
316
317   if (Res == ERROR_NO_DATA)
318   {
319     printf("No interfaces detected.\n");
320     return;
321   }
322   
323   if (Res != NO_ERROR)
324   {
325     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
326     return;
327   }
328
329   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
330   {
331     OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index)
332
333     MiniIndexToIntName(IntName, Walker->Index);
334
335     printf("%s: ", IntName);
336
337     IsWlan = IsWireless(IntName);
338
339     if (IsWlan < 0)
340       printf("?");
341
342     else if (IsWlan == 0)
343       printf("-");
344
345     else
346       printf("+");
347
348     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
349          Walker2 = Walker2->Next)
350       printf(" %s", Walker2->IpAddress.String);
351
352     printf("\n");
353   }
354 }
355
356 void RemoveInterface(struct olsr_if *IntConf)
357 {
358   struct interface *Int, *Prev;
359
360   OLSR_PRINTF(1, "Removing interface %s.\n", IntConf->name)
361   
362   Int = IntConf->interf;
363
364   run_ifchg_cbs(Int, IFCHG_IF_ADD);
365
366   if (Int == ifnet)
367     ifnet = Int->int_next;
368
369   else
370   {
371     for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
372
373     Prev->int_next = Int->int_next;
374   }
375
376   if(COMP_IP(&main_addr, &Int->ip_addr))
377   {
378     if(ifnet == NULL)
379     {
380       memset(&main_addr, 0, ipsize);
381       OLSR_PRINTF(1, "Removed last interface. Cleared main address.\n")
382     }
383
384     else
385     {
386       COPY_IP(&main_addr, &ifnet->ip_addr);
387       OLSR_PRINTF(1, "New main address: %s.\n", olsr_ip_to_string(&main_addr))
388     }
389   }
390
391   if (olsr_cnf->lq_level == 0)
392     {
393       olsr_remove_scheduler_event(&generate_hello, Int,
394                                   IntConf->cnf->hello_params.emission_interval,
395                                   0, NULL);
396
397       olsr_remove_scheduler_event(&generate_tc, Int,
398                                   IntConf->cnf->tc_params.emission_interval,
399                                   0, NULL);
400     }
401
402   else
403     {
404       olsr_remove_scheduler_event(&olsr_output_lq_hello, Int,
405                                   IntConf->cnf->hello_params.emission_interval,
406                                   0, NULL);
407
408       olsr_remove_scheduler_event(&olsr_output_lq_tc, Int,
409                                   IntConf->cnf->tc_params.emission_interval,
410                                   0, NULL);
411     }
412
413   olsr_remove_scheduler_event(&generate_mid, Int,
414                               IntConf->cnf->mid_params.emission_interval,
415                               0, NULL);
416
417   olsr_remove_scheduler_event(&generate_hna, Int,
418                               IntConf->cnf->hna_params.emission_interval,
419                               0, NULL);
420
421   net_remove_buffer(Int);
422
423   IntConf->configured = 0;
424   IntConf->interf = NULL;
425
426   closesocket(Int->olsr_socket);
427   remove_olsr_socket(Int->olsr_socket, &olsr_input);
428
429   free(Int->int_name);
430   free(Int);
431
432   if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
433   {
434     OLSR_PRINTF(1, "No more active interfaces - exiting.\n")
435     exit_value = EXIT_FAILURE;
436     CallSignalHandler();
437   }
438 }
439
440 int chk_if_changed(struct olsr_if *IntConf)
441 {
442   struct interface *Int;
443   struct InterfaceInfo Info;
444   int Res;
445   int IsWlan;
446   union olsr_ip_addr OldVal, NewVal;
447   struct sockaddr_in *AddrIn;
448
449   if (olsr_cnf->ip_version == AF_INET6)
450   {
451     fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
452     return 0;
453   }
454
455 #ifdef DEBUG
456   OLSR_PRINTF(3, "Checking if %s is set down or changed\n", IntConf->name)
457 #endif
458
459   Int = IntConf->interf;
460
461   if (GetIntInfo(&Info, IntConf->name) < 0)
462   {
463     RemoveInterface(IntConf);
464     return 1;
465   }
466
467   Res = 0;
468
469   IsWlan = IsWireless(IntConf->name);
470
471   if (IsWlan < 0)
472     IsWlan = 1;
473
474   if (Int->is_wireless != IsWlan)
475   {
476     OLSR_PRINTF(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan)
477
478     Int->is_wireless = IsWlan;
479
480     if (IntConf->cnf->weight.fixed)
481       Int->int_metric = IntConf->cnf->weight.value;
482
483     else
484       Int->int_metric = IsWlan;
485
486     Res = 1;
487   }
488
489   if (Int->int_mtu != Info.Mtu)
490   {
491     OLSR_PRINTF(1, "\tMTU change: %d -> %d.\n", (int)Int->int_mtu,
492                 Info.Mtu);
493
494     Int->int_mtu = Info.Mtu;
495
496     net_remove_buffer(Int);
497     net_add_buffer(Int);
498
499     Res = 1;
500   }
501
502   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr.s_addr;
503   NewVal.v4 = Info.Addr;
504
505 #ifdef DEBUG
506   OLSR_PRINTF(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal))
507 #endif
508
509   if (NewVal.v4 != OldVal.v4)
510   {
511     OLSR_PRINTF(1, "\tAddress change.\n")
512     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
513     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
514
515     Int->ip_addr.v4 = NewVal.v4;
516
517     AddrIn = (struct sockaddr_in *)&Int->int_addr;
518
519     AddrIn->sin_family = AF_INET;
520     AddrIn->sin_port = 0;
521     AddrIn->sin_addr.s_addr = NewVal.v4;
522
523     if (main_addr.v4 == OldVal.v4)
524     {
525       OLSR_PRINTF(1, "\tMain address change.\n")
526
527       main_addr.v4 = NewVal.v4;
528     }
529
530     Res = 1;
531   }
532
533   else
534     OLSR_PRINTF(3, "\tNo address change.\n")
535
536   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr.s_addr;
537   NewVal.v4 = Info.Mask;
538
539 #ifdef DEBUG
540   OLSR_PRINTF(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal))
541 #endif
542
543   if (NewVal.v4 != OldVal.v4)
544   {
545     OLSR_PRINTF(1, "\tNetmask change.\n")
546     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
547     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
548
549     AddrIn = (struct sockaddr_in *)&Int->int_netmask;
550
551     AddrIn->sin_family = AF_INET;
552     AddrIn->sin_port = 0;
553     AddrIn->sin_addr.s_addr = NewVal.v4;
554
555     Res = 1;
556   }
557
558   else
559     OLSR_PRINTF(3, "\tNo netmask change.\n")
560
561   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr.s_addr;
562   NewVal.v4 = Info.Broad;
563
564 #ifdef DEBUG
565   OLSR_PRINTF(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal))
566 #endif
567
568   if (NewVal.v4 != OldVal.v4)
569   {
570     OLSR_PRINTF(1, "\tBroadcast address change.\n")
571     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
572     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
573
574     AddrIn = (struct sockaddr_in *)&Int->int_broadaddr;
575
576     AddrIn->sin_family = AF_INET;
577     AddrIn->sin_port = 0;
578     AddrIn->sin_addr.s_addr = NewVal.v4;
579
580     Res = 1;
581   }
582
583   else
584     OLSR_PRINTF(3, "\tNo broadcast address change.\n")
585
586   if (Res != 0)
587     run_ifchg_cbs(Int, IFCHG_IF_UPDATE);
588
589   return Res;
590 }
591
592 int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
593 {
594   struct InterfaceInfo Info;
595   struct interface *New;
596   union olsr_ip_addr NullAddr;
597   unsigned int AddrSockAddr;
598   int IsWlan;
599   struct sockaddr_in *AddrIn;
600   
601   if (olsr_cnf->ip_version == AF_INET6)
602   {
603     fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
604     return 0;
605   }
606
607   if (GetIntInfo(&Info, IntConf->name) < 0)
608     return 0;
609
610   New = olsr_malloc(sizeof (struct interface), "Interface 1");
611   New->gen_properties = NULL;
612
613   AddrIn = (struct sockaddr_in *)&New->int_addr;
614
615   AddrIn->sin_family = AF_INET;
616   AddrIn->sin_port = 0;
617   AddrIn->sin_addr.s_addr = Info.Addr;
618
619   AddrIn = (struct sockaddr_in *)&New->int_netmask;
620
621   AddrIn->sin_family = AF_INET;
622   AddrIn->sin_port = 0;
623   AddrIn->sin_addr.s_addr = Info.Mask;
624
625   AddrIn = (struct sockaddr_in *)&New->int_broadaddr;
626
627   AddrIn->sin_family = AF_INET;
628   AddrIn->sin_port = 0;
629   AddrIn->sin_addr.s_addr = Info.Broad;
630
631   if (IntConf->cnf->ipv4_broadcast.v4 != 0)
632     AddrIn->sin_addr.s_addr = IntConf->cnf->ipv4_broadcast.v4;
633
634   New->int_flags = 0;
635
636   New->int_mtu = Info.Mtu;
637
638   New->int_name = olsr_malloc(strlen (IntConf->name) + 1, "Interface 2");
639   strcpy(New->int_name, IntConf->name);
640
641   New->if_nr = IntConf->index;
642
643   IsWlan = IsWireless(IntConf->name);
644
645   if (IsWlan < 0)
646     IsWlan = 1;
647
648   New->is_wireless = IsWlan;
649
650   if (IntConf->cnf->weight.fixed)
651     New->int_metric = IntConf->cnf->weight.value;
652
653   else
654     New->int_metric = IsWlan;
655
656   New->olsr_seqnum = random() & 0xffff;
657     
658   OLSR_PRINTF(1, "\tInterface %s set up for use with index %d\n\n",
659               IntConf->name, New->if_nr)
660       
661   OLSR_PRINTF(1, "\tMTU: %d\n", New->int_mtu)
662   OLSR_PRINTF(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr))
663   OLSR_PRINTF(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask))
664   OLSR_PRINTF(1, "\tBroadcast address: %s\n",
665               sockaddr_to_string(&New->int_broadaddr))
666
667   New->ip_addr.v4 =
668     ((struct sockaddr_in *)&New->int_addr)->sin_addr.s_addr;
669       
670   New->if_index = Info.Index;
671
672   OLSR_PRINTF(3, "\tKernel index: %08x\n", New->if_index)
673
674   AddrSockAddr = addrsock.sin_addr.s_addr;
675   addrsock.sin_addr.s_addr = New->ip_addr.v4;
676
677   New->olsr_socket = getsocket((struct sockaddr *)&addrsock,
678                                127 * 1024, New->int_name);
679       
680   addrsock.sin_addr.s_addr = AddrSockAddr;
681
682   if (New->olsr_socket < 0)
683   {
684     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
685     exit(1);
686   }
687
688   add_olsr_socket(New->olsr_socket, &olsr_input);
689
690   New->int_next = ifnet;
691   ifnet = New;
692
693   IntConf->interf = New;
694   IntConf->configured = 1;
695
696   memset(&NullAddr, 0, ipsize);
697   
698   if(COMP_IP(&NullAddr, &main_addr))
699   {
700     COPY_IP(&main_addr, &New->ip_addr);
701     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&main_addr))
702   }
703
704   net_add_buffer(New);
705
706   if (olsr_cnf->lq_level == 0)
707   {
708     olsr_register_scheduler_event(&generate_hello, New,
709                                   IntConf->cnf->hello_params.emission_interval,
710                                   0, NULL);
711
712     olsr_register_scheduler_event(&generate_tc, New,
713                                   IntConf->cnf->tc_params.emission_interval,
714                                   0, NULL);
715   }
716
717   else
718   {
719     olsr_register_scheduler_event(&olsr_output_lq_hello, New,
720                                   IntConf->cnf->hello_params.emission_interval,
721                                   0, NULL);
722
723     olsr_register_scheduler_event(&olsr_output_lq_tc, New,
724                                   IntConf->cnf->tc_params.emission_interval,
725                                   0, NULL);
726   }
727
728   olsr_register_scheduler_event(&generate_mid, New,
729                                 IntConf->cnf->mid_params.emission_interval,
730                                 0, NULL);
731
732   olsr_register_scheduler_event(&generate_hna, New,
733                                 IntConf->cnf->hna_params.emission_interval,
734                                 0, NULL);
735
736   if(max_jitter == 0 ||
737      IntConf->cnf->hello_params.emission_interval / 4 < max_jitter)
738     max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
739
740   if(max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
741     max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
742
743   New->hello_etime =
744     double_to_me(IntConf->cnf->hello_params.emission_interval);
745
746   New->valtimes.hello = double_to_me(IntConf->cnf->hello_params.validity_time);
747   New->valtimes.tc = double_to_me(IntConf->cnf->tc_params.validity_time);
748   New->valtimes.mid = double_to_me(IntConf->cnf->mid_params.validity_time);
749   New->valtimes.hna = double_to_me(IntConf->cnf->hna_params.validity_time);
750
751   run_ifchg_cbs(New, IFCHG_IF_ADD);
752
753   return 1;
754 }
755
756 void check_interface_updates(void *dummy)
757 {
758   struct olsr_if *IntConf;
759
760 #ifdef DEBUG
761   OLSR_PRINTF(3, "Checking for updates in the interface set\n")
762 #endif
763
764   for(IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next)
765   {
766     if(IntConf->configured)    
767       chk_if_changed(IntConf);
768
769     else
770       chk_if_up(IntConf, 3);
771   }
772 }