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