General cleanups in header files
[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.16 2005/02/20 18:52:19 kattemat 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
503   olsr_printf(1, "Removing interface %s.\n", IntConf->name);
504   
505   Int = IntConf->interf;
506
507   run_ifchg_cbs(Int, IFCHG_IF_ADD);
508
509   if (Int == ifnet)
510     ifnet = Int->int_next;
511
512   else
513   {
514     for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
515
516     Prev->int_next = Int->int_next;
517   }
518
519   if(COMP_IP(&main_addr, &Int->ip_addr))
520   {
521     if(ifnet == NULL)
522     {
523       memset(&main_addr, 0, ipsize);
524       olsr_printf(1, "Removed last interface. Cleared main address.\n");
525     }
526
527     else
528     {
529       COPY_IP(&main_addr, &ifnet->ip_addr);
530       olsr_printf(1, "New main address: %s.\n", olsr_ip_to_string(&main_addr));
531     }
532   }
533
534   if (olsr_cnf->lq_level == 0)
535     {
536       olsr_remove_scheduler_event(&generate_hello, Int,
537                                   IntConf->cnf->hello_params.emission_interval,
538                                   0, NULL);
539
540       olsr_remove_scheduler_event(&generate_tc, Int,
541                                   IntConf->cnf->tc_params.emission_interval,
542                                   0, NULL);
543     }
544
545   else
546     {
547       olsr_remove_scheduler_event(&olsr_output_lq_hello, Int,
548                                   IntConf->cnf->hello_params.emission_interval,
549                                   0, NULL);
550
551       olsr_remove_scheduler_event(&olsr_output_lq_tc, Int,
552                                   IntConf->cnf->tc_params.emission_interval,
553                                   0, NULL);
554     }
555
556   olsr_remove_scheduler_event(&generate_mid, Int,
557                               IntConf->cnf->mid_params.emission_interval,
558                               0, NULL);
559
560   olsr_remove_scheduler_event(&generate_hna, Int,
561                               IntConf->cnf->hna_params.emission_interval,
562                               0, NULL);
563
564   net_remove_buffer(Int);
565
566   IntConf->configured = 0;
567   IntConf->interf = NULL;
568
569   closesocket(Int->olsr_socket);
570   remove_olsr_socket(Int->olsr_socket, &olsr_input);
571
572   free(Int->int_name);
573   free(Int);
574
575   if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
576   {
577     olsr_printf(1, "No more active interfaces - exiting.\n");
578     exit_value = EXIT_FAILURE;
579     CallSignalHandler();
580   }
581 }
582
583 int chk_if_changed(struct olsr_if *IntConf)
584 {
585   struct interface *Int;
586   INTERFACE_INFO IntInfo;
587   MIB_IFROW IntRow;
588   int Index;
589   int Res;
590   union olsr_ip_addr OldVal, NewVal;
591   int IsWlan;
592
593   if (olsr_cnf->ip_version == AF_INET6)
594   {
595     fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
596     return 0;
597   }
598
599 #ifdef DEBUG
600   olsr_printf(3, "Checking if %s is set down or changed\n", IntConf->name);
601 #endif
602
603   Int = IntConf->interf;
604
605   if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
606       InterfaceEntry(&IntRow, &Index, IntConf))
607   {
608     RemoveInterface(IntConf);
609     return 1;
610   }
611
612   Res = 0;
613
614   IsWlan = IsWireless(IntConf->name);
615
616   if (IsWlan < 0)
617     IsWlan = 1;
618
619   if (Int->is_wireless != IsWlan)
620   {
621     olsr_printf(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan);
622
623     Int->is_wireless = IsWlan;
624     if(IntConf->cnf->weight.fixed)
625       Int->int_metric = IntConf->cnf->weight.value;
626     else
627       Int->int_metric = IsWlan;
628
629     Res = 1;
630   }
631
632   if (Int->int_mtu != IntRow.dwMtu)
633   {
634     olsr_printf(1, "\tMTU change: %d -> %d.\n", Int->int_mtu, IntRow.dwMtu);
635
636     Int->int_mtu = IntRow.dwMtu;
637
638     net_remove_buffer(Int);
639     net_add_buffer(Int);
640
641     Res = 1;
642   }
643
644   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr.s_addr;
645   NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiAddress)->sin_addr.s_addr;
646
647 #ifdef DEBUG
648   olsr_printf(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal));
649 #endif
650
651   if (NewVal.v4 != OldVal.v4)
652   {
653     olsr_printf(1, "\tAddress change.\n");
654     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
655     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
656
657     Int->ip_addr.v4 = NewVal.v4;
658
659     memcpy(&Int->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
660
661     if (main_addr.v4 == OldVal.v4)
662     {
663       olsr_printf(1, "\tMain address change.\n");
664
665       main_addr.v4 = NewVal.v4;
666     }
667
668     Res = 1;
669   }
670
671   else
672     olsr_printf(3, "\tNo address change.\n");
673
674   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr.s_addr;
675   NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiNetmask)->sin_addr.s_addr;
676
677 #ifdef DEBUG
678   olsr_printf(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal));
679 #endif
680
681   if(NewVal.v4 != OldVal.v4)
682   {
683     olsr_printf(1, "\tNetmask change.\n");
684     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
685     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
686
687     memcpy(&Int->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
688
689     Res = 1;
690   }
691
692   else
693     olsr_printf(3, "\tNo netmask change.\n");
694
695   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr.s_addr;
696   NewVal.v4 =
697     ((struct sockaddr_in *)&IntInfo.iiBroadcastAddress)->sin_addr.s_addr;
698
699 #ifdef DEBUG
700   olsr_printf(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal));
701 #endif
702
703   if(NewVal.v4 != OldVal.v4)
704   {
705     olsr_printf(1, "\tBroadcast address change.\n");
706     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
707     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
708
709     memcpy(&Int->int_broadaddr, &IntInfo.iiBroadcastAddress,
710            sizeof (struct sockaddr_in));
711
712     Res = 1;
713   }
714
715   else
716     olsr_printf(3, "\tNo broadcast address change.\n");
717
718   if (Res != 0)
719     run_ifchg_cbs(Int, IFCHG_IF_UPDATE);
720
721   return Res;
722 }
723
724 int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
725 {
726   struct interface *New;
727   union olsr_ip_addr NullAddr;
728   INTERFACE_INFO IntInfo;
729   MIB_IFROW IntRow;
730   int Index;
731   unsigned int AddrSockAddr;
732   int IsWlan;
733   
734   if (olsr_cnf->ip_version == AF_INET6)
735   {
736     fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
737     return 0;
738   }
739
740   if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
741       InterfaceEntry(&IntRow, &Index, IntConf) < 0)
742     return 0;
743
744   New = olsr_malloc(sizeof (struct interface), "Interface 1");
745       
746   memcpy(&New->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
747
748   memcpy(&New->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
749
750   memcpy(&New->int_broadaddr, &IntInfo.iiBroadcastAddress,
751          sizeof (struct sockaddr_in));
752
753   if (IntConf->cnf->ipv4_broadcast.v4 != 0)
754     ((struct sockaddr_in *)&New->int_broadaddr)->sin_addr.s_addr =
755       IntConf->cnf->ipv4_broadcast.v4;
756
757   New->int_flags = IntInfo.iiFlags;
758
759   New->int_mtu = IntRow.dwMtu;
760
761   New->int_name = olsr_malloc(strlen (IntConf->name) + 1, "Interface 2");
762   strcpy(New->int_name, IntConf->name);
763
764   New->if_nr = IntConf->index;
765
766   IsWlan = IsWireless(IntConf->name);
767
768   if (IsWlan < 0)
769     IsWlan = 1;
770
771   New->is_wireless = IsWlan;
772   if(IntConf->cnf->weight.fixed)
773     New->int_metric = IntConf->cnf->weight.value;
774   else
775     New->int_metric = IsWlan;
776
777   New->olsr_seqnum = random() & 0xffff;
778     
779   olsr_printf(1, "\tInterface %s set up for use with index %d\n\n",
780               IntConf->name, New->if_nr);
781       
782   olsr_printf(1, "\tMTU: %d\n", New->int_mtu);
783   olsr_printf(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr));
784   olsr_printf(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask));
785   olsr_printf(1, "\tBroadcast address: %s\n",
786               sockaddr_to_string(&New->int_broadaddr));
787
788   New->ip_addr.v4 =
789     ((struct sockaddr_in *)&New->int_addr)->sin_addr.s_addr;
790       
791   New->if_index = Index;
792
793   olsr_printf(3, "\tKernel index: %08x\n", New->if_index);
794
795   AddrSockAddr = addrsock.sin_addr.s_addr;
796   addrsock.sin_addr.s_addr = New->ip_addr.v4;
797
798   New->olsr_socket = getsocket((struct sockaddr *)&addrsock,
799                                127 * 1024, New->int_name);
800       
801   addrsock.sin_addr.s_addr = AddrSockAddr;
802
803   if (New->olsr_socket < 0)
804   {
805     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
806     exit(1);
807   }
808
809   add_olsr_socket(New->olsr_socket, &olsr_input);
810
811   New->int_next = ifnet;
812   ifnet = New;
813
814   IntConf->interf = New;
815   IntConf->configured = 1;
816
817   memset(&NullAddr, 0, ipsize);
818   
819   if(COMP_IP(&NullAddr, &main_addr))
820   {
821     COPY_IP(&main_addr, &New->ip_addr);
822
823     olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
824   }
825
826   net_add_buffer(New);
827
828   if (olsr_cnf->lq_level == 0)
829     {
830       olsr_register_scheduler_event(&generate_hello, New,
831                                     IntConf->cnf->hello_params.emission_interval,
832                                     0, NULL);
833
834       olsr_register_scheduler_event(&generate_tc, New,
835                                     IntConf->cnf->tc_params.emission_interval,
836                                     0, NULL);
837     }
838
839   else
840     {
841       olsr_register_scheduler_event(&olsr_output_lq_hello, New,
842                                     IntConf->cnf->hello_params.emission_interval,
843                                     0, NULL);
844
845       olsr_register_scheduler_event(&olsr_output_lq_tc, New,
846                                     IntConf->cnf->tc_params.emission_interval,
847                                     0, NULL);
848     }
849
850   olsr_register_scheduler_event(&generate_mid, New,
851                                 IntConf->cnf->mid_params.emission_interval,
852                                 0, NULL);
853
854   olsr_register_scheduler_event(&generate_hna, New,
855                                 IntConf->cnf->hna_params.emission_interval,
856                                 0, NULL);
857
858   if(max_jitter == 0 ||
859      IntConf->cnf->hello_params.emission_interval / 4 < max_jitter)
860     max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
861
862   if(max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
863     max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
864
865   New->hello_etime =
866     double_to_me(IntConf->cnf->hello_params.emission_interval);
867
868   New->valtimes.hello = double_to_me(IntConf->cnf->hello_params.validity_time);
869   New->valtimes.tc = double_to_me(IntConf->cnf->tc_params.validity_time);
870   New->valtimes.mid = double_to_me(IntConf->cnf->mid_params.validity_time);
871   New->valtimes.hna = double_to_me(IntConf->cnf->hna_params.validity_time);
872
873   run_ifchg_cbs(Int, IFCHG_IF_ADD);
874
875   return 1;
876 }
877
878 void check_interface_updates(void *dummy)
879 {
880   struct olsr_if *IntConf;
881
882 #ifdef DEBUG
883   olsr_printf(3, "Checking for updates in the interface set\n");
884 #endif
885
886   for(IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next)
887   {
888     if(IntConf->configured)    
889       chk_if_changed(IntConf);
890
891     else
892       chk_if_up(IntConf, 3);
893   }
894 }