BSD-style license.
[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.12 2004/11/21 01:21:10 tlopatic Exp $
40  */
41
42 #include "../interfaces.h"
43 #include "../olsr.h"
44 #include "../net.h"
45 #include "../parser.h"
46 #include "../socket_parser.h"
47 #include "../defs.h"
48 #include "../net_os.h"
49 #include "../ifnet.h"
50 #include "../generate_msg.h"
51 #include "../scheduler.h"
52 #include "../mantissa.h"
53
54 #include <iphlpapi.h>
55 #include <iprtrmib.h>
56
57 void WinSockPError(char *);
58 char *StrError(unsigned int ErrNo);
59 int inet_pton(int af, char *src, void *dst);
60
61 void ListInterfaces(void);
62 int InterfaceEntry(MIB_IFROW *IntPara, int *Index, struct olsr_if *IntConf);
63 int InterfaceInfo(INTERFACE_INFO *IntPara, int *Index,
64                   struct olsr_if *IntConf);
65 void RemoveInterface(struct olsr_if *IntConf);
66
67 #define MAX_INTERFACES 25
68
69 int __stdcall SignalHandler(unsigned long Signal);
70
71 static unsigned long __stdcall SignalHandlerWrapper(void *Dummy)
72 {
73   SignalHandler(0);
74   return 0;
75 }
76
77 static void CallSignalHandler(void)
78 {
79   unsigned long ThreadId;
80
81   CreateThread(NULL, 0, SignalHandlerWrapper, NULL, 0, &ThreadId);
82 }
83
84 static void MiniIndexToIntName(char *String, int MiniIndex)
85 {
86   char *HexDigits = "0123456789abcdef";
87
88   String[0] = 'i';
89   String[1] = 'f';
90
91   String[2] = HexDigits[(MiniIndex >> 4) & 15];
92   String[3] = HexDigits[MiniIndex & 15];
93
94   String[4] = 0;
95 }
96
97 static int IntNameToMiniIndex(int *MiniIndex, char *String)
98 {
99   char *HexDigits = "0123456789abcdef";
100   int i, k;
101   char ch;
102
103   if ((String[0] != 'i' && String[0] != 'I') ||
104       (String[1] != 'f' && String[1] != 'F'))
105     return -1;
106
107   *MiniIndex = 0;
108
109   for (i = 2; i < 4; i++)
110   {
111     ch = String[i];
112
113     if (ch >= 'A' && ch <= 'F')
114       ch += 32;
115
116     for (k = 0; k < 16 && ch != HexDigits[k]; k++);
117
118     if (k == 16)
119       return -1;
120
121     *MiniIndex = (*MiniIndex << 4) | k;
122   }
123
124   return 0;
125 }
126
127 static int MiniIndexToGuid(char *Guid, int MiniIndex)
128 {
129   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
130   unsigned long AdInfoLen;
131   unsigned long Res;
132   
133   if (olsr_cnf->ip_version == AF_INET6)
134   {
135     fprintf(stderr, "IPv6 not supported by MiniIndexToGuid()!\n");
136     return -1;
137   }
138
139   AdInfoLen = sizeof (AdInfo);
140
141   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
142
143   if (Res != NO_ERROR)
144   {
145     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(),
146             StrError(Res));
147     return -1;
148   }
149
150   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
151   {
152     olsr_printf(5, "Index = %08x\n", Walker->Index);
153
154     if ((Walker->Index & 255) == MiniIndex)
155       break;
156   }
157
158   if (Walker != NULL)
159   {
160     olsr_printf(5, "Found interface.\n");
161
162     strcpy(Guid, Walker->AdapterName);
163     return 0;
164   }
165
166   olsr_printf(5, "Cannot map mini index %02x to an adapter GUID.\n",
167               MiniIndex);
168   return -1;
169 }
170
171 static int AddrToIndex(int *Index, unsigned int Addr)
172 {
173   unsigned int IntAddr;
174   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
175   unsigned long AdInfoLen;
176   IP_ADDR_STRING *Walker2;
177   unsigned long Res;
178   
179   olsr_printf(5, "AddrToIndex(%08x)\n", Addr);
180
181   if (olsr_cnf->ip_version == AF_INET6)
182   {
183     fprintf(stderr, "IPv6 not supported by AddrToIndex()!\n");
184     return -1;
185   }
186
187   AdInfoLen = sizeof (AdInfo);
188
189   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
190
191   if (Res != NO_ERROR)
192   {
193     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
194     return -1;
195   }
196
197   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
198   {
199     olsr_printf(5, "Index = %08x\n", Walker->Index);
200
201     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
202          Walker2 = Walker2->Next)
203     {
204       inet_pton(AF_INET, Walker2->IpAddress.String, &IntAddr);
205
206       olsr_printf(5, "\tIP address = %08x\n", IntAddr);
207
208       if (Addr == IntAddr)
209       {
210         olsr_printf(5, "Found interface.\n");
211         *Index = Walker->Index;
212         return 0;
213       }
214     }
215   }
216
217   olsr_printf(5, "Cannot map IP address %08x to an adapter index.\n", Addr);
218   return -1;
219 }
220
221 #if !defined OID_802_11_CONFIGURATION
222 #define OID_802_11_CONFIGURATION 0x0d010211
223 #endif
224
225 #if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS
226 #define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
227 #endif
228
229 static int IsWireless(char *IntName)
230 {
231   int MiniIndex;
232   char DevName[43];
233   HANDLE DevHand;
234   unsigned int ErrNo;
235   unsigned int Oid;
236   unsigned char OutBuff[100];
237   unsigned long OutBytes;
238
239   if (IntNameToMiniIndex(&MiniIndex, IntName) < 0)
240     return -1;
241
242   DevName[0] = '\\';
243   DevName[1] = '\\';
244   DevName[2] = '.';
245   DevName[3] = '\\';
246
247   if (MiniIndexToGuid(DevName + 4, MiniIndex) < 0)
248     return -1;
249
250   olsr_printf(5, "Checking whether interface %s is wireless.\n", DevName);
251
252   DevHand = CreateFile(DevName, GENERIC_READ,
253                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
254                        FILE_ATTRIBUTE_NORMAL, NULL);
255
256   if (DevHand == INVALID_HANDLE_VALUE)
257   {
258     ErrNo = GetLastError();
259
260     olsr_printf(5, "CreateFile() = %08lx, %s\n", ErrNo, StrError(ErrNo));
261     return -1;
262   }
263
264   Oid = OID_802_11_CONFIGURATION;
265
266   if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS,
267                        &Oid, sizeof (Oid),
268                        OutBuff, sizeof (OutBuff),
269                        &OutBytes, NULL))
270   {
271     ErrNo = GetLastError();
272
273     CloseHandle(DevHand);
274
275     if (ErrNo == ERROR_GEN_FAILURE)
276     {
277       olsr_printf(5, "OID not supported. Device probably not wireless.\n");
278       return 0;
279     }
280
281     olsr_printf(5, "DeviceIoControl() = %08lx, %s\n", ErrNo, StrError(ErrNo));
282     return -1;
283   }
284
285   CloseHandle(DevHand);
286   return 1;
287 }
288
289 void ListInterfaces(void)
290 {
291   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
292   unsigned long AdInfoLen;
293   char IntName[5];
294   IP_ADDR_STRING *Walker2;
295   unsigned long Res;
296   int IsWlan;
297   
298   if (olsr_cnf->ip_version == AF_INET6)
299   {
300     fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n");
301     return;
302   }
303
304   AdInfoLen = sizeof (AdInfo);
305
306   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
307
308   if (Res == ERROR_NO_DATA)
309   {
310     printf("No interfaces detected.\n");
311     return;
312   }
313   
314   if (Res != NO_ERROR)
315   {
316     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
317     return;
318   }
319
320   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
321   {
322     olsr_printf(5, "Index = %08x\n", Walker->Index);
323
324     MiniIndexToIntName(IntName, Walker->Index);
325
326     printf("%s: ", IntName);
327
328     IsWlan = IsWireless(IntName);
329
330     if (IsWlan < 0)
331       printf("?");
332
333     else if (IsWlan == 0)
334       printf("-");
335
336     else
337       printf("+");
338
339     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
340          Walker2 = Walker2->Next)
341       printf(" %s", Walker2->IpAddress.String);
342
343     printf("\n");
344   }
345 }
346
347 int InterfaceEntry(MIB_IFROW *IntPara, int *Index, struct olsr_if *IntConf)
348 {
349   int MiniIndex;
350   unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4];
351   MIB_IFTABLE *IfTable;
352   unsigned long BuffLen;
353   unsigned long Res;
354   int TabIdx;
355
356   if (olsr_cnf->ip_version == AF_INET6)
357   {
358     fprintf(stderr, "IPv6 not supported by AdapterInfo()!\n");
359     return -1;
360   }
361
362   if (IntNameToMiniIndex(&MiniIndex, IntConf->name) < 0)
363   {
364     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
365     return -1;
366   }
367
368   IfTable = (MIB_IFTABLE *)Buff;
369
370   BuffLen = sizeof (Buff);
371
372   Res = GetIfTable(IfTable, &BuffLen, FALSE);
373
374   if (Res != NO_ERROR)
375   {
376     fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
377     return -1;
378   }
379
380   for (TabIdx = 0; TabIdx < IfTable->dwNumEntries; TabIdx++)
381   {
382     olsr_printf(5, "Index = %08x\n", IfTable->table[TabIdx].dwIndex);
383
384     if ((IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
385       break;
386   }
387
388   if (TabIdx == IfTable->dwNumEntries)
389   {
390     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
391     return -1;
392   }
393     
394   *Index = IfTable->table[TabIdx].dwIndex;
395
396   memcpy(IntPara, &IfTable->table[TabIdx], sizeof (MIB_IFROW));
397   return 0;
398 }
399
400 int InterfaceInfo(INTERFACE_INFO *IntPara, int *Index, struct olsr_if *IntConf)
401 {
402   int MiniIndex;
403   int Sock;
404   INTERFACE_INFO IntInfo[25];
405   long Num;
406   int WsIdx;
407   int CandIndex;
408
409   if (IntNameToMiniIndex(&MiniIndex, IntConf->name) < 0)
410   {
411     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
412     return -1;
413   }
414
415   Sock = socket(olsr_cnf->ip_version, SOCK_STREAM, IPPROTO_TCP);
416
417   if (Sock < 0)
418   {
419     WinSockPError("socket()");
420     return -1;
421   }
422
423   if (WSAIoctl(Sock, SIO_GET_INTERFACE_LIST, NULL, 0,
424                IntInfo, sizeof (IntInfo), &Num, NULL, NULL) < 0)
425   {
426     WinSockPError("WSAIoctl(SIO_GET_INTERFACE_LIST)");
427     closesocket(Sock);
428     return -1;
429   }
430
431   closesocket(Sock);
432
433   Num /= sizeof (INTERFACE_INFO);
434
435   olsr_printf(5, "%s:\n", IntConf->name);
436
437   for (WsIdx = 0; WsIdx < Num; WsIdx++)
438   {
439     if (AddrToIndex(&CandIndex,
440                     IntInfo[WsIdx].iiAddress.AddressIn.sin_addr.s_addr) < 0)
441       continue;
442
443     if ((CandIndex & 255) == MiniIndex)
444       break;
445   }
446
447   if (WsIdx == Num)
448   {
449     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
450     return -1;
451   }
452     
453   *Index = CandIndex;
454
455   olsr_printf(5, "\tIndex: %08x\n", *Index);
456
457   olsr_printf(5, "\tFlags: %08x\n", IntInfo[WsIdx].iiFlags);
458
459   if ((IntInfo[WsIdx].iiFlags & IFF_UP) == 0)
460   {
461     olsr_printf(1, "\tInterface not up - skipping it...\n");
462     return -1;
463   }
464
465   if (olsr_cnf->ip_version == AF_INET &&
466       (IntInfo[WsIdx].iiFlags & IFF_BROADCAST) == 0)
467   {
468     olsr_printf(1, "\tNo broadcast - skipping it...\n");
469     return -1;
470   }
471
472   if ((IntInfo[WsIdx].iiFlags & IFF_LOOPBACK) != 0)
473   {
474     olsr_printf(1, "\tThis is a loopback interface - skipping it...\n");
475     return -1;
476   }
477
478   // Windows seems to always return 255.255.255.255 as broadcast
479   // address, so I've tried using (address | ~netmask).
480
481   {
482     struct sockaddr_in *sin_a, *sin_n, *sin_b;
483     unsigned int a, n, b;
484
485     sin_a = (struct sockaddr_in *)&IntInfo[WsIdx].iiAddress;
486     sin_n = (struct sockaddr_in *)&IntInfo[WsIdx].iiNetmask;
487     sin_b = (struct sockaddr_in *)&IntInfo[WsIdx].iiBroadcastAddress;
488
489     a = sin_a->sin_addr.s_addr;
490     n = sin_n->sin_addr.s_addr;
491     b = sin_b->sin_addr.s_addr =
492       sin_a->sin_addr.s_addr | ~sin_n->sin_addr.s_addr;
493   }
494
495   memcpy(IntPara, &IntInfo[WsIdx], sizeof (INTERFACE_INFO));
496   return 0;
497 }
498
499 void RemoveInterface(struct olsr_if *IntConf)
500 {
501   struct interface *Int, *Prev;
502   struct ifchgf *Walker;
503
504   olsr_printf(1, "Removing interface %s.\n", IntConf->name);
505   
506   Int = IntConf->interf;
507
508   for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
509     Walker->function(Int, IFCHG_IF_REMOVE);
510
511   if (Int == ifnet)
512     ifnet = Int->int_next;
513
514   else
515   {
516     for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
517
518     Prev->int_next = Int->int_next;
519   }
520
521   if(COMP_IP(&main_addr, &Int->ip_addr))
522   {
523     if(ifnet == NULL)
524     {
525       memset(&main_addr, 0, ipsize);
526       olsr_printf(1, "Removed last interface. Cleared main address.\n");
527     }
528
529     else
530     {
531       COPY_IP(&main_addr, &ifnet->ip_addr);
532       olsr_printf(1, "New main address: %s.\n", olsr_ip_to_string(&main_addr));
533     }
534   }
535
536 #if defined USE_LINK_QUALITY
537   if (olsr_cnf->lq_level == 0)
538     {
539 #endif
540       olsr_remove_scheduler_event(&generate_hello, Int,
541                                   IntConf->cnf->hello_params.emission_interval,
542                                   0, NULL);
543
544       olsr_remove_scheduler_event(&generate_tc, Int,
545                                   IntConf->cnf->tc_params.emission_interval,
546                                   0, NULL);
547 #if defined USE_LINK_QUALITY
548     }
549
550   else
551     {
552       olsr_remove_scheduler_event(&olsr_output_lq_hello, Int,
553                                   IntConf->cnf->hello_params.emission_interval,
554                                   0, NULL);
555
556       olsr_remove_scheduler_event(&olsr_output_lq_tc, Int,
557                                   IntConf->cnf->tc_params.emission_interval,
558                                   0, NULL);
559     }
560 #endif
561   olsr_remove_scheduler_event(&generate_mid, Int,
562                               IntConf->cnf->mid_params.emission_interval,
563                               0, NULL);
564
565   olsr_remove_scheduler_event(&generate_hna, Int,
566                               IntConf->cnf->hna_params.emission_interval,
567                               0, NULL);
568
569   net_remove_buffer(Int);
570
571   IntConf->configured = 0;
572   IntConf->interf = NULL;
573
574   closesocket(Int->olsr_socket);
575   remove_olsr_socket(Int->olsr_socket, &olsr_input);
576
577   free(Int->int_name);
578   free(Int);
579
580   if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
581   {
582     olsr_printf(1, "No more active interfaces - exiting.\n");
583     exit_value = EXIT_FAILURE;
584     CallSignalHandler();
585   }
586 }
587
588 int chk_if_changed(struct olsr_if *IntConf)
589 {
590   struct interface *Int;
591   INTERFACE_INFO IntInfo;
592   MIB_IFROW IntRow;
593   int Index;
594   int Res;
595   union olsr_ip_addr OldVal, NewVal;
596   struct ifchgf *Walker;
597   int IsWlan;
598
599   if (olsr_cnf->ip_version == AF_INET6)
600   {
601     fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
602     return 0;
603   }
604
605 #ifdef DEBUG
606   olsr_printf(3, "Checking if %s is set down or changed\n", IntConf->name);
607 #endif
608
609   Int = IntConf->interf;
610
611   if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
612       InterfaceEntry(&IntRow, &Index, IntConf))
613   {
614     RemoveInterface(IntConf);
615     return 1;
616   }
617
618   Res = 0;
619
620   IsWlan = IsWireless(IntConf->name);
621
622   if (IsWlan < 0)
623     IsWlan = 1;
624
625   if (Int->is_wireless != IsWlan)
626   {
627     olsr_printf(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan);
628
629     Int->is_wireless = IsWlan;
630     Int->int_metric = IsWlan;
631
632     Res = 1;
633   }
634
635   if (Int->int_mtu != IntRow.dwMtu)
636   {
637     olsr_printf(1, "\tMTU change: %d -> %d.\n", Int->int_mtu, IntRow.dwMtu);
638
639     Int->int_mtu = IntRow.dwMtu;
640
641     net_remove_buffer(Int);
642     net_add_buffer(Int);
643
644     Res = 1;
645   }
646
647   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr.s_addr;
648   NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiAddress)->sin_addr.s_addr;
649
650 #ifdef DEBUG
651   olsr_printf(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal));
652 #endif
653
654   if (NewVal.v4 != OldVal.v4)
655   {
656     olsr_printf(1, "\tAddress change.\n");
657     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
658     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
659
660     Int->ip_addr.v4 = NewVal.v4;
661
662     memcpy(&Int->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
663
664     if (main_addr.v4 == OldVal.v4)
665     {
666       olsr_printf(1, "\tMain address change.\n");
667
668       main_addr.v4 = NewVal.v4;
669     }
670
671     Res = 1;
672   }
673
674   else
675     olsr_printf(3, "\tNo address change.\n");
676
677   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr.s_addr;
678   NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiNetmask)->sin_addr.s_addr;
679
680 #ifdef DEBUG
681   olsr_printf(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal));
682 #endif
683
684   if(NewVal.v4 != OldVal.v4)
685   {
686     olsr_printf(1, "\tNetmask change.\n");
687     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
688     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
689
690     memcpy(&Int->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
691
692     Res = 1;
693   }
694
695   else
696     olsr_printf(3, "\tNo netmask change.\n");
697
698   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr.s_addr;
699   NewVal.v4 =
700     ((struct sockaddr_in *)&IntInfo.iiBroadcastAddress)->sin_addr.s_addr;
701
702 #ifdef DEBUG
703   olsr_printf(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal));
704 #endif
705
706   if(NewVal.v4 != OldVal.v4)
707   {
708     olsr_printf(1, "\tBroadcast address change.\n");
709     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
710     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
711
712     memcpy(&Int->int_broadaddr, &IntInfo.iiBroadcastAddress,
713            sizeof (struct sockaddr_in));
714
715     Res = 1;
716   }
717
718   else
719     olsr_printf(3, "\tNo broadcast address change.\n");
720
721   if (Res != 0)
722     for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
723       Walker->function(Int, IFCHG_IF_UPDATE);
724
725   return Res;
726 }
727
728 int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
729 {
730   struct interface *New;
731   union olsr_ip_addr NullAddr;
732   INTERFACE_INFO IntInfo;
733   MIB_IFROW IntRow;
734   int Index;
735   unsigned int AddrSockAddr;
736   struct ifchgf *Walker;
737   int IsWlan;
738   
739   if (olsr_cnf->ip_version == AF_INET6)
740   {
741     fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
742     return 0;
743   }
744
745   if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
746       InterfaceEntry(&IntRow, &Index, IntConf) < 0)
747     return 0;
748
749   New = olsr_malloc(sizeof (struct interface), "Interface 1");
750       
751   memcpy(&New->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
752
753   memcpy(&New->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
754
755   memcpy(&New->int_broadaddr, &IntInfo.iiBroadcastAddress,
756          sizeof (struct sockaddr_in));
757
758   if (IntConf->cnf->ipv4_broadcast.v4 != 0)
759     ((struct sockaddr_in *)&New->int_broadaddr)->sin_addr.s_addr =
760       IntConf->cnf->ipv4_broadcast.v4;
761
762   New->int_flags = IntInfo.iiFlags;
763
764   New->int_mtu = IntRow.dwMtu;
765
766   New->int_name = olsr_malloc(strlen (IntConf->name) + 1, "Interface 2");
767   strcpy(New->int_name, IntConf->name);
768
769   New->if_nr = IntConf->index;
770
771   IsWlan = IsWireless(IntConf->name);
772
773   if (IsWlan < 0)
774     IsWlan = 1;
775
776   New->is_wireless = IsWlan;
777   New->int_metric = IsWlan;
778
779   New->olsr_seqnum = random() & 0xffff;
780     
781   olsr_printf(1, "\tInterface %s set up for use with index %d\n\n",
782               IntConf->name, New->if_nr);
783       
784   olsr_printf(1, "\tMTU: %d\n", New->int_mtu);
785   olsr_printf(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr));
786   olsr_printf(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask));
787   olsr_printf(1, "\tBroadcast address: %s\n",
788               sockaddr_to_string(&New->int_broadaddr));
789
790   New->ip_addr.v4 =
791     ((struct sockaddr_in *)&New->int_addr)->sin_addr.s_addr;
792       
793   New->if_index = Index;
794
795   olsr_printf(3, "\tKernel index: %08x\n", New->if_index);
796
797   AddrSockAddr = addrsock.sin_addr.s_addr;
798   addrsock.sin_addr.s_addr = New->ip_addr.v4;
799
800   New->olsr_socket = getsocket((struct sockaddr *)&addrsock,
801                                127 * 1024, New->int_name);
802       
803   addrsock.sin_addr.s_addr = AddrSockAddr;
804
805   if (New->olsr_socket < 0)
806   {
807     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
808     exit(1);
809   }
810
811   add_olsr_socket(New->olsr_socket, &olsr_input);
812
813   New->int_next = ifnet;
814   ifnet = New;
815
816   IntConf->interf = New;
817   IntConf->configured = 1;
818
819   memset(&NullAddr, 0, ipsize);
820   
821   if(COMP_IP(&NullAddr, &main_addr))
822   {
823     COPY_IP(&main_addr, &New->ip_addr);
824
825     olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
826   }
827
828   net_add_buffer(New);
829
830 #if defined USE_LINK_QUALITY
831   if (olsr_cnf->lq_level == 0)
832     {
833 #endif
834       olsr_register_scheduler_event(&generate_hello, New,
835                                     IntConf->cnf->hello_params.emission_interval,
836                                     0, NULL);
837
838       olsr_register_scheduler_event(&generate_tc, New,
839                                     IntConf->cnf->tc_params.emission_interval,
840                                     0, NULL);
841 #if defined USE_LINK_QUALITY
842     }
843
844   else
845     {
846       olsr_register_scheduler_event(&olsr_output_lq_hello, New,
847                                     IntConf->cnf->hello_params.emission_interval,
848                                     0, NULL);
849
850       olsr_register_scheduler_event(&olsr_output_lq_tc, New,
851                                     IntConf->cnf->tc_params.emission_interval,
852                                     0, NULL);
853     }
854 #endif
855   olsr_register_scheduler_event(&generate_mid, New,
856                                 IntConf->cnf->mid_params.emission_interval,
857                                 0, NULL);
858
859   olsr_register_scheduler_event(&generate_hna, New,
860                                 IntConf->cnf->hna_params.emission_interval,
861                                 0, NULL);
862
863   if(max_jitter == 0 ||
864      IntConf->cnf->hello_params.emission_interval / 4 < max_jitter)
865     max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
866
867   if(max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
868     max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
869
870   New->hello_etime =
871     double_to_me(IntConf->cnf->hello_params.emission_interval);
872
873   New->valtimes.hello = double_to_me(IntConf->cnf->hello_params.validity_time);
874   New->valtimes.tc = double_to_me(IntConf->cnf->tc_params.validity_time);
875   New->valtimes.mid = double_to_me(IntConf->cnf->mid_params.validity_time);
876   New->valtimes.hna = double_to_me(IntConf->cnf->hna_params.validity_time);
877
878   for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
879     Walker->function(New, IFCHG_IF_ADD);
880
881   return 1;
882 }
883
884 void check_interface_updates(void *dummy)
885 {
886   struct olsr_if *IntConf;
887
888 #ifdef DEBUG
889   olsr_printf(3, "Checking for updates in the interface set\n");
890 #endif
891
892   for(IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next)
893   {
894     if(IntConf->configured)    
895       chk_if_changed(IntConf);
896
897     else
898       chk_if_up(IntConf, 3);
899   }
900 }