58d0c6f005d3e2b4cb60d2ec582395cebf220002
[olsrd.git] / src / win32 / ifnet.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon (olsrd)
4  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #ifdef _WIN32
43
44 #include <stdlib.h>
45 #define random() rand()
46 #define srandom(x) srand(x)
47 #include <winsock2.h>
48 #include "interfaces.h"
49 #include "olsr.h"
50 #include "parser.h"
51 #include "defs.h"
52 #include "net_os.h"
53 #include "ifnet.h"
54 #include "generate_msg.h"
55 #include "scheduler.h"
56 #include "mantissa.h"
57 #include "lq_packet.h"
58 #include "net_olsr.h"
59
60 #include <iphlpapi.h>
61 #include <iprtrmib.h>
62
63 #include <arpa/inet.h>
64
65 #define BUFSPACE  (127*1024)    /* max. input buffer size to request */
66
67 struct MibIpInterfaceRow {
68   USHORT Family;
69   ULONG64 InterfaceLuid;
70   ULONG InterfaceIndex;
71   ULONG MaxReassemblySize;
72   ULONG64 InterfaceIdentifier;
73   ULONG MinRouterAdvertisementInterval;
74   ULONG MaxRouterAdvertisementInterval;
75   BOOLEAN AdvertisingEnabled;
76   BOOLEAN ForwardingEnabled;
77   BOOLEAN WeakHostSend;
78   BOOLEAN WeakHostReceive;
79   BOOLEAN UseAutomaticMetric;
80   BOOLEAN UseNeighborUnreachabilityDetection;
81   BOOLEAN ManagedAddressConfigurationSupported;
82   BOOLEAN OtherStatefulConfigurationSupported;
83   BOOLEAN AdvertiseDefaultRoute;
84   INT RouterDiscoveryBehavior;
85   ULONG DadTransmits;
86   ULONG BaseReachableTime;
87   ULONG RetransmitTime;
88   ULONG PathMtuDiscoveryTimeout;
89   INT LinkLocalAddressBehavior;
90   ULONG LinkLocalAddressTimeout;
91   ULONG ZoneIndices[16];
92   ULONG SitePrefixLength;
93   ULONG Metric;
94   ULONG NlMtu;
95   BOOLEAN Connected;
96   BOOLEAN SupportsWakeUpPatterns;
97   BOOLEAN SupportsNeighborDiscovery;
98   BOOLEAN SupportsRouterDiscovery;
99   ULONG ReachableTime;
100   BYTE TransmitOffload;
101   BYTE ReceiveOffload;
102   BOOLEAN DisableDefaultRoutes;
103 };
104
105 typedef DWORD(__stdcall * GETIPINTERFACEENTRY) (struct MibIpInterfaceRow * Row);
106
107 typedef DWORD(__stdcall * GETADAPTERSADDRESSES) (ULONG Family, DWORD Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses,
108                                                  PULONG pOutBufLen);
109
110 struct InterfaceInfo {
111   unsigned int Index;
112   int Mtu;
113   int Metric;
114   unsigned int Addr;
115   unsigned int Mask;
116   unsigned int Broad;
117   char Guid[39];
118 };
119
120 void WinSockPError(char *);
121 char *StrError(unsigned int ErrNo);
122
123 void ListInterfaces(void);
124 int GetIntInfo(struct InterfaceInfo *Info, char *Name);
125
126 #define MAX_INTERFACES 100
127
128 static void
129 MiniIndexToIntName(char *String, int MiniIndex)
130 {
131   const char *HexDigits = "0123456789abcdef";
132
133   String[0] = 'i';
134   String[1] = 'f';
135
136   String[2] = HexDigits[(MiniIndex >> 4) & 15];
137   String[3] = HexDigits[MiniIndex & 15];
138
139   String[4] = 0;
140 }
141
142 static int
143 IntNameToMiniIndex(int *MiniIndex, char *String)
144 {
145   const char *HexDigits = "0123456789abcdef";
146   int i, k;
147   char ch;
148
149   if ((String[0] != 'i' && String[0] != 'I') || (String[1] != 'f' && String[1] != 'F'))
150     return -1;
151
152   *MiniIndex = 0;
153
154   for (i = 2; i < 4; i++) {
155     ch = String[i];
156
157     if (ch >= 'A' && ch <= 'F')
158       ch += 32;
159
160     for (k = 0; k < 16 && ch != HexDigits[k]; k++);
161
162     if (k == 16)
163       return -1;
164
165     *MiniIndex = (*MiniIndex << 4) | k;
166   }
167
168   return 0;
169 }
170
171 static int
172 FriendlyNameToMiniIndex(int *MiniIndex, char *String)
173 {
174   unsigned long BuffLen;
175   unsigned long Res;
176   IP_ADAPTER_ADDRESSES AdAddr[MAX_INTERFACES], *WalkerAddr;
177   char FriendlyName[MAX_INTERFACE_NAME_LEN];
178   HMODULE h;
179   GETADAPTERSADDRESSES pfGetAdaptersAddresses;
180
181   h = LoadLibrary("iphlpapi.dll");
182
183   if (h == NULL) {
184     fprintf(stderr, "LoadLibrary() = %08lx", GetLastError());
185     return -1;
186   }
187
188   pfGetAdaptersAddresses = (GETADAPTERSADDRESSES) GetProcAddress(h, "GetAdaptersAddresses");
189
190   if (pfGetAdaptersAddresses == NULL) {
191     fprintf(stderr, "Unable to use adapter friendly name (GetProcAddress() = %08lx)\n", GetLastError());
192     return -1;
193   }
194
195   BuffLen = sizeof(AdAddr);
196
197   Res = pfGetAdaptersAddresses(AF_INET, 0, NULL, AdAddr, &BuffLen);
198
199   if (Res != NO_ERROR) {
200     fprintf(stderr, "GetAdaptersAddresses() = %08lx", GetLastError());
201     return -1;
202   }
203
204   for (WalkerAddr = AdAddr; WalkerAddr != NULL; WalkerAddr = WalkerAddr->Next) {
205     OLSR_PRINTF(5, "Index = %08x - ", (int)WalkerAddr->IfIndex);
206
207     wcstombs(FriendlyName, WalkerAddr->FriendlyName, MAX_INTERFACE_NAME_LEN);
208
209     OLSR_PRINTF(5, "Friendly name = %s\n", FriendlyName);
210
211     if (strncmp(FriendlyName, String, MAX_INTERFACE_NAME_LEN) == 0)
212       break;
213   }
214
215   if (WalkerAddr == NULL) {
216     fprintf(stderr, "No such interface: %s!\n", String);
217     return -1;
218   }
219
220   *MiniIndex = WalkerAddr->IfIndex & 255;
221
222   return 0;
223 }
224
225 int
226 GetIntInfo(struct InterfaceInfo *Info, char *Name)
227 {
228   int MiniIndex;
229   unsigned char Buff[MAX_INTERFACES * sizeof(MIB_IFROW) + 4];
230   MIB_IFTABLE *IfTable;
231   unsigned long BuffLen;
232   unsigned long Res;
233   int TabIdx;
234   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
235   HMODULE Lib;
236   struct MibIpInterfaceRow Row;
237   GETIPINTERFACEENTRY InterfaceEntry;
238
239   if (olsr_cnf->ip_version == AF_INET6) {
240     fprintf(stderr, "IPv6 not supported by GetIntInfo()!\n");
241     return -1;
242   }
243
244   if ((Name[0] != 'i' && Name[0] != 'I') || (Name[1] != 'f' && Name[1] != 'F')) {
245     if (FriendlyNameToMiniIndex(&MiniIndex, Name) < 0) {
246       fprintf(stderr, "No such interface: %s!\n", Name);
247       return -1;
248     }
249   }
250
251   else {
252     if (IntNameToMiniIndex(&MiniIndex, Name) < 0) {
253       fprintf(stderr, "No such interface: %s!\n", Name);
254       return -1;
255     }
256   }
257
258   IfTable = (MIB_IFTABLE *) Buff;
259
260   BuffLen = sizeof(Buff);
261
262   Res = GetIfTable(IfTable, &BuffLen, FALSE);
263
264   if (Res != NO_ERROR) {
265     fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
266     return -1;
267   }
268
269   for (TabIdx = 0; TabIdx < (int)IfTable->dwNumEntries; TabIdx++) {
270     OLSR_PRINTF(5, "Index = %08x\n", (int)IfTable->table[TabIdx].dwIndex);
271
272     if ((int)(IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
273       break;
274   }
275
276   if (TabIdx == (int)IfTable->dwNumEntries) {
277     fprintf(stderr, "No such interface: %s!\n", Name);
278     return -1;
279   }
280
281   Info->Index = IfTable->table[TabIdx].dwIndex;
282   Info->Mtu = (int)IfTable->table[TabIdx].dwMtu;
283
284   Info->Mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
285
286   Lib = LoadLibrary("iphlpapi.dll");
287
288   if (Lib == NULL) {
289     fprintf(stderr, "Cannot load iphlpapi.dll: %08lx\n", GetLastError());
290     return -1;
291   }
292
293   InterfaceEntry = (GETIPINTERFACEENTRY) GetProcAddress(Lib, "GetIpInterfaceEntry");
294
295   if (InterfaceEntry == NULL) {
296     OLSR_PRINTF(5, "Not running on Vista - setting interface metric to 0.\n");
297
298     Info->Metric = 0;
299   }
300
301   else {
302     memset(&Row, 0, sizeof(struct MibIpInterfaceRow));
303
304     Row.Family = AF_INET;
305     Row.InterfaceIndex = Info->Index;
306
307     Res = InterfaceEntry(&Row);
308
309     if (Res != NO_ERROR) {
310       fprintf(stderr, "GetIpInterfaceEntry() = %08lx", Res);
311       FreeLibrary(Lib);
312       return -1;
313     }
314
315     Info->Metric = Row.Metric;
316
317     OLSR_PRINTF(5, "Running on Vista - interface metric is %d.\n", Info->Metric);
318   }
319
320   FreeLibrary(Lib);
321
322   BuffLen = sizeof(AdInfo);
323
324   Res = GetAdaptersInfo(AdInfo, &BuffLen);
325
326   if (Res != NO_ERROR) {
327     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(), StrError(Res));
328     return -1;
329   }
330
331   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next) {
332     OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
333
334     if ((int)(Walker->Index & 255) == MiniIndex)
335       break;
336   }
337
338   if (Walker == NULL) {
339     fprintf(stderr, "No such interface: %s!\n", Name);
340     return -1;
341   }
342
343   inet_pton(AF_INET, Walker->IpAddressList.IpAddress.String, &Info->Addr);
344   inet_pton(AF_INET, Walker->IpAddressList.IpMask.String, &Info->Mask);
345
346   Info->Broad = Info->Addr | ~Info->Mask;
347
348   strscpy(Info->Guid, Walker->AdapterName, sizeof(Info->Guid));
349
350   if ((IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED
351        && IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL) || Info->Addr == 0) {
352     OLSR_PRINTF(3, "Interface %s not up!\n", Name);
353     return -1;
354   }
355
356   return 0;
357 }
358
359 #if !defined OID_802_11_CONFIGURATION
360 #define OID_802_11_CONFIGURATION 0x0d010211
361 #endif /* !defined OID_802_11_CONFIGURATION */
362
363 #if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS
364 #define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
365 #endif /* !defined IOCTL_NDIS_QUERY_GLOBAL_STATS */
366
367 static int
368 IsWireless(char *IntName)
369 {
370 #if !defined WINCE
371   struct InterfaceInfo Info;
372   char DevName[43];
373   HANDLE DevHand;
374   unsigned int ErrNo;
375   unsigned int Oid;
376   unsigned char OutBuff[100];
377   unsigned long OutBytes;
378
379   if (GetIntInfo(&Info, IntName) < 0)
380     return -1;
381
382   DevName[0] = '\\';
383   DevName[1] = '\\';
384   DevName[2] = '.';
385   DevName[3] = '\\';
386
387   strscpy(DevName + 4, Info.Guid, sizeof(DevName) - 4);
388
389   OLSR_PRINTF(5, "Checking whether interface %s is wireless.\n", DevName);
390
391   DevHand = CreateFile(DevName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
392
393   if (DevHand == INVALID_HANDLE_VALUE) {
394     ErrNo = GetLastError();
395
396     OLSR_PRINTF(5, "CreateFile() = %08x, %s\n", ErrNo, StrError(ErrNo));
397     return -1;
398   }
399
400   Oid = OID_802_11_CONFIGURATION;
401
402   if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS, &Oid, sizeof(Oid), OutBuff, sizeof(OutBuff), &OutBytes, NULL)) {
403     ErrNo = GetLastError();
404
405     CloseHandle(DevHand);
406
407     if (ErrNo == ERROR_GEN_FAILURE || ErrNo == ERROR_INVALID_PARAMETER) {
408       OLSR_PRINTF(5, "OID not supported. Device probably not wireless.\n");
409       return 0;
410     }
411
412     OLSR_PRINTF(5, "DeviceIoControl() = %08x, %s\n", ErrNo, StrError(ErrNo));
413     return -1;
414   }
415
416   CloseHandle(DevHand);
417 #endif /* !defined WINCE */
418   return 1;
419 }
420
421 void
422 ListInterfaces(void)
423 {
424   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
425   unsigned long AdInfoLen;
426   char IntName[5];
427   IP_ADDR_STRING *Walker2;
428   unsigned long Res;
429   int IsWlan;
430
431   if (olsr_cnf->ip_version == AF_INET6) {
432     fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n");
433     return;
434   }
435
436   AdInfoLen = sizeof(AdInfo);
437
438   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
439
440   if (Res == ERROR_NO_DATA) {
441     printf("No interfaces detected.\n");
442     return;
443   }
444
445   if (Res != NO_ERROR) {
446     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
447     return;
448   }
449
450   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next) {
451     OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
452
453     MiniIndexToIntName(IntName, Walker->Index);
454
455     printf("%s: ", IntName);
456
457     IsWlan = IsWireless(IntName);
458
459     if (IsWlan < 0)
460       printf("?");
461
462     else if (IsWlan == 0)
463       printf("-");
464
465     else
466       printf("+");
467
468     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL; Walker2 = Walker2->Next)
469       printf(" %s", Walker2->IpAddress.String);
470
471     printf("\n");
472   }
473 }
474
475 int
476 add_hemu_if(struct olsr_if *iface)
477 {
478   struct interface *ifp;
479   union olsr_ip_addr null_addr;
480   uint32_t addr[4];
481   struct ipaddr_str buf;
482   size_t name_size;
483
484   if (!iface->host_emul)
485     return -1;
486
487   ifp = olsr_malloc(sizeof(struct interface), "Interface update 2");
488
489   memset(ifp, 0, sizeof(struct interface));
490
491   /* initialize backpointer */
492   ifp->olsr_if = iface;
493
494   iface->configured = true;
495   iface->interf = ifp;
496
497   name_size = strlen("hcif01") + 1;
498   ifp->is_hcif = true;
499   ifp->int_name = olsr_malloc(name_size, "Interface update 3");
500   ifp->int_metric = 0;
501
502   strscpy(ifp->int_name, "hcif01", name_size);
503
504   OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
505
506   OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
507
508   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
509
510   ifp->int_next = ifnet;
511   ifnet = ifp;
512
513   memset(&null_addr, 0, olsr_cnf->ipsize);
514   if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
515     olsr_cnf->main_addr = iface->hemu_ip;
516     olsr_cnf->unicast_src_ip = iface->hemu_ip;
517     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
518   }
519
520   ifp->int_mtu = OLSR_DEFAULT_MTU;
521
522   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
523
524   /* Set up buffer */
525   net_add_buffer(ifp);
526
527   if (olsr_cnf->ip_version == AF_INET) {
528     struct sockaddr_in sin;
529
530     memset(&sin, 0, sizeof(sin));
531
532     sin.sin_family = AF_INET;
533     sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
534     sin.sin_port = htons(10150);
535
536     /* IP version 4 */
537     ifp->ip_addr.v4 = iface->hemu_ip.v4;
538
539     memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
540
541     /*
542      *We create one socket for each interface and bind
543      *the socket to it. This to ensure that we can control
544      *on what interface the message is transmitted
545      */
546
547     ifp->olsr_socket = gethemusocket(&sin);
548
549     if (ifp->olsr_socket < 0) {
550       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
551       exit(1);
552     }
553
554   } else {
555     /* IP version 6 */
556     memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
557   }
558
559   /* Send IP as first 4/16 bytes on socket */
560   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
561   addr[0] = htonl(addr[0]);
562   addr[1] = htonl(addr[1]);
563   addr[2] = htonl(addr[2]);
564   addr[3] = htonl(addr[3]);
565
566   if (send(ifp->olsr_socket, (char *)addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize) {
567     fprintf(stderr, "Error sending IP!");
568   }
569
570   /* Register socket */
571   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu, NULL, NULL, SP_PR_READ);
572
573   /*
574    * Register functions for periodic message generation
575    */
576   ifp->hello_gen_timer =
577     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
578                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
579   ifp->tc_gen_timer =
580     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
581                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
582   ifp->mid_gen_timer =
583     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
584                      mid_gen_timer_cookie);
585   ifp->hna_gen_timer =
586     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
587                      hna_gen_timer_cookie);
588
589   /* Recalculate max topology hold time */
590   if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
591     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
592
593   ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
594   ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
595   ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
596   ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
597   ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
598
599   ifp->mode = iface->cnf->mode;
600
601   return 1;
602 }
603
604 int
605 chk_if_changed(struct olsr_if *iface)
606 {
607   struct ipaddr_str buf;
608   struct interface *Int;
609   struct InterfaceInfo Info;
610   int Res;
611   int IsWlan;
612   union olsr_ip_addr OldVal, NewVal;
613   struct sockaddr_in *AddrIn;
614
615   if (olsr_cnf->ip_version == AF_INET6) {
616     fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
617     return 0;
618   }
619 #ifdef DEBUG
620   OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
621 #endif /* DEBUG */
622
623   Int = iface->interf;
624
625   if (GetIntInfo(&Info, iface->name) < 0) {
626     olsr_remove_interface(iface);
627     return 1;
628   }
629
630   Res = 0;
631
632   IsWlan = IsWireless(iface->name);
633
634   if (IsWlan < 0)
635     IsWlan = 1;
636
637   if (Int->is_wireless != IsWlan) {
638     OLSR_PRINTF(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan);
639
640     Int->is_wireless = IsWlan;
641
642     if (iface->cnf->weight.fixed)
643       Int->int_metric = iface->cnf->weight.value;
644
645     else
646       Int->int_metric = Info.Metric;
647
648     Res = 1;
649   }
650
651   if (Int->int_mtu != Info.Mtu) {
652     OLSR_PRINTF(1, "\tMTU change: %d -> %d.\n", (int)Int->int_mtu, Info.Mtu);
653
654     Int->int_mtu = Info.Mtu;
655
656     net_remove_buffer(Int);
657     net_add_buffer(Int);
658
659     Res = 1;
660   }
661
662   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr;
663   NewVal.v4.s_addr = Info.Addr;
664
665 #ifdef DEBUG
666   OLSR_PRINTF(3, "\tAddress: %s\n", olsr_ip_to_string(&buf, &NewVal));
667 #endif /* DEBUG */
668
669   if (NewVal.v4.s_addr != OldVal.v4.s_addr) {
670     OLSR_PRINTF(1, "\tAddress change.\n");
671     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&buf, &OldVal));
672     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&buf, &NewVal));
673
674     Int->ip_addr.v4 = NewVal.v4;
675
676     AddrIn = (struct sockaddr_in *)&Int->int_addr;
677
678     AddrIn->sin_family = AF_INET;
679     AddrIn->sin_port = 0;
680     AddrIn->sin_addr = NewVal.v4;
681
682     if (olsr_cnf->main_addr.v4.s_addr == OldVal.v4.s_addr) {
683       OLSR_PRINTF(1, "\tMain address change.\n");
684
685       olsr_cnf->main_addr.v4 = NewVal.v4;
686     }
687
688     Res = 1;
689   }
690
691   else
692     OLSR_PRINTF(3, "\tNo address change.\n");
693
694   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr;
695   NewVal.v4.s_addr = Info.Mask;
696
697 #ifdef DEBUG
698   OLSR_PRINTF(3, "\tNetmask: %s\n", olsr_ip_to_string(&buf, &NewVal));
699 #endif /* DEBUG */
700
701   if (NewVal.v4.s_addr != OldVal.v4.s_addr) {
702     OLSR_PRINTF(1, "\tNetmask change.\n");
703     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&buf, &OldVal));
704     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&buf, &NewVal));
705
706     AddrIn = (struct sockaddr_in *)&Int->int_netmask;
707
708     AddrIn->sin_family = AF_INET;
709     AddrIn->sin_port = 0;
710     AddrIn->sin_addr = NewVal.v4;
711
712     Res = 1;
713   }
714
715   else
716     OLSR_PRINTF(3, "\tNo netmask change.\n");
717
718   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr;
719   NewVal.v4.s_addr = Info.Broad;
720
721 #ifdef DEBUG
722   OLSR_PRINTF(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&buf, &NewVal));
723 #endif /* DEBUG */
724
725   if (NewVal.v4.s_addr != OldVal.v4.s_addr) {
726     OLSR_PRINTF(1, "\tBroadcast address change.\n");
727     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&buf, &OldVal));
728     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&buf, &NewVal));
729
730     AddrIn = (struct sockaddr_in *)&Int->int_broadaddr;
731
732     AddrIn->sin_family = AF_INET;
733     AddrIn->sin_port = 0;
734     AddrIn->sin_addr = NewVal.v4;
735
736     Res = 1;
737   }
738
739   else
740     OLSR_PRINTF(3, "\tNo broadcast address change.\n");
741
742   if (Res != 0)
743     olsr_trigger_ifchange(Int->if_index, Int, IFCHG_IF_UPDATE);
744
745   return Res;
746 }
747
748 int
749 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
750 {
751   struct ipaddr_str buf;
752   struct InterfaceInfo Info;
753   struct interface *New;
754   union olsr_ip_addr NullAddr;
755   int IsWlan;
756   struct sockaddr_in *AddrIn;
757   size_t name_size;
758
759   if (olsr_cnf->ip_version == AF_INET6) {
760     fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
761     return 0;
762   }
763
764   if (GetIntInfo(&Info, iface->name) < 0)
765     return 0;
766
767   New = olsr_malloc(sizeof(struct interface), "Interface 1");
768   /* initialize backpointer */
769   New->olsr_if = iface;
770
771
772   New->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
773   if (olsr_cnf->max_jitter == 0) {
774     /* max_jitter determines the max time to store to-be-send-messages, correlated with random() */
775     olsr_cnf->max_jitter =
776       New->immediate_send_tc ? iface->cnf->tc_params.emission_interval : iface->cnf->hello_params.emission_interval;
777   }
778
779   New->gen_properties = NULL;
780
781   AddrIn = (struct sockaddr_in *)&New->int_addr;
782
783   AddrIn->sin_family = AF_INET;
784   AddrIn->sin_port = 0;
785   AddrIn->sin_addr.s_addr = Info.Addr;
786
787   AddrIn = (struct sockaddr_in *)&New->int_netmask;
788
789   AddrIn->sin_family = AF_INET;
790   AddrIn->sin_port = 0;
791   AddrIn->sin_addr.s_addr = Info.Mask;
792
793   AddrIn = (struct sockaddr_in *)&New->int_broadaddr;
794
795   AddrIn->sin_family = AF_INET;
796   AddrIn->sin_port = 0;
797   AddrIn->sin_addr.s_addr = Info.Broad;
798
799   if (iface->cnf->ipv4_multicast.v4.s_addr != 0)
800     AddrIn->sin_addr = iface->cnf->ipv4_multicast.v4;
801
802   New->int_flags = 0;
803
804   New->is_hcif = false;
805
806   New->int_mtu = Info.Mtu;
807
808   name_size = strlen(iface->name) + 1;
809   New->int_name = olsr_malloc(name_size, "Interface 2");
810   strscpy(New->int_name, iface->name, name_size);
811
812   IsWlan = IsWireless(iface->name);
813
814   if (IsWlan < 0)
815     IsWlan = 1;
816
817   New->is_wireless = IsWlan;
818
819   if (iface->cnf->weight.fixed)
820     New->int_metric = iface->cnf->weight.value;
821
822   else
823     New->int_metric = Info.Metric;
824
825   New->olsr_seqnum = random() & 0xffff;
826
827   New->ttl_index = -32;         /* For the first 32 TC's, fish-eye is disabled */
828
829   OLSR_PRINTF(1, "\tInterface %s set up for use with index %d\n\n", iface->name, New->if_index);
830
831   OLSR_PRINTF(1, "\tMTU: %d\n", New->int_mtu);
832   OLSR_PRINTF(1, "\tAddress: %s\n", sockaddr4_to_string(&buf, (const struct sockaddr *)&New->int_addr));
833   OLSR_PRINTF(1, "\tNetmask: %s\n", sockaddr4_to_string(&buf, (const struct sockaddr *)&New->int_netmask));
834   OLSR_PRINTF(1, "\tBroadcast address: %s\n", sockaddr4_to_string(&buf, (const struct sockaddr *)&New->int_broadaddr));
835
836   New->ip_addr.v4 = New->int_addr.sin_addr;
837
838   New->if_index = Info.Index;
839
840   OLSR_PRINTF(3, "\tKernel index: %08x\n", New->if_index);
841
842   New->olsr_socket = getsocket(BUFSPACE, New);
843   New->send_socket = getsocket(0, New);
844
845   if (New->olsr_socket < 0) {
846     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
847     exit(1);
848   }
849
850   add_olsr_socket(New->olsr_socket, &olsr_input, NULL, NULL, SP_PR_READ);
851
852   New->int_next = ifnet;
853   ifnet = New;
854
855   iface->interf = New;
856   iface->configured = 1;
857
858   memset(&NullAddr, 0, olsr_cnf->ipsize);
859
860   if (ipequal(&NullAddr, &olsr_cnf->main_addr)) {
861     olsr_cnf->main_addr = New->ip_addr;
862     olsr_cnf->unicast_src_ip = New->ip_addr;
863     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
864   }
865
866   net_add_buffer(New);
867
868   /*
869    * Register functions for periodic message generation
870    */
871   New->hello_gen_timer =
872     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
873                      olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, New, hello_gen_timer_cookie);
874   New->tc_gen_timer =
875     olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
876                      olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, New, tc_gen_timer_cookie);
877   New->mid_gen_timer =
878     olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, New,
879                      mid_gen_timer_cookie);
880   New->hna_gen_timer =
881     olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, New,
882                      hna_gen_timer_cookie);
883
884   if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
885     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
886
887   New->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
888   New->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
889   New->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
890   New->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
891   New->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
892
893   New->mode = iface->cnf->mode;
894
895   olsr_trigger_ifchange(New->if_index, New, IFCHG_IF_ADD);
896
897   return 1;
898 }
899
900 void
901 check_interface_updates(void *dummy __attribute__ ((unused)))
902 {
903   struct olsr_if *IntConf;
904
905 #ifdef DEBUG
906   OLSR_PRINTF(3, "Checking for updates in the interface set\n");
907 #endif /* DEBUG */
908
909   for (IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next) {
910     if (IntConf->host_emul)
911       continue;
912
913     if (olsr_cnf->host_emul)    /* XXX: TEMPORARY! */
914       continue;
915
916     if (IntConf->configured)
917       chk_if_changed(IntConf);
918
919     else
920       chk_if_up(IntConf, 3);
921   }
922 }
923
924 #endif /* _WIN32 */
925
926 /*
927  * Local Variables:
928  * c-basic-offset: 2
929  * indent-tabs-mode: nil
930  * End:
931  */