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