639ddb64a6a6e4aef9957f7b44b57e4c65cf10f3
[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.31 2006/10/11 20:18:36 tlopatic Exp $
40  */
41
42 #include "interfaces.h"
43 #include "olsr.h"
44 #include "parser.h"
45 #include "socket_parser.h"
46 #include "defs.h"
47 #include "net_os.h"
48 #include "ifnet.h"
49 #include "generate_msg.h"
50 #include "scheduler.h"
51 #include "mantissa.h"
52 #include "lq_packet.h"
53
54 #include <iphlpapi.h>
55 #include <iprtrmib.h>
56
57 struct InterfaceInfo
58 {
59   unsigned int Index;
60   int Mtu;
61   unsigned int Addr;
62   unsigned int Mask;
63   unsigned int Broad;
64   char Guid[39];
65 };
66
67 void WinSockPError(char *);
68 char *StrError(unsigned int ErrNo);
69 int inet_pton(int af, char *src, void *dst);
70
71 void ListInterfaces(void);
72 int GetIntInfo(struct InterfaceInfo *Info, char *Name);
73 void RemoveInterface(struct olsr_if *IntConf);
74
75 #define MAX_INTERFACES 25
76
77 int __stdcall SignalHandler(unsigned long Signal);
78
79 static unsigned long __stdcall SignalHandlerWrapper(void *Dummy)
80 {
81   SignalHandler(0);
82   return 0;
83 }
84
85 static void CallSignalHandler(void)
86 {
87   unsigned long ThreadId;
88
89   CreateThread(NULL, 0, SignalHandlerWrapper, NULL, 0, &ThreadId);
90 }
91
92 static void MiniIndexToIntName(char *String, int MiniIndex)
93 {
94   char *HexDigits = "0123456789abcdef";
95
96   String[0] = 'i';
97   String[1] = 'f';
98
99   String[2] = HexDigits[(MiniIndex >> 4) & 15];
100   String[3] = HexDigits[MiniIndex & 15];
101
102   String[4] = 0;
103 }
104
105 static int IntNameToMiniIndex(int *MiniIndex, char *String)
106 {
107   char *HexDigits = "0123456789abcdef";
108   int i, k;
109   char ch;
110
111   if ((String[0] != 'i' && String[0] != 'I') ||
112       (String[1] != 'f' && String[1] != 'F'))
113     return -1;
114
115   *MiniIndex = 0;
116
117   for (i = 2; i < 4; i++)
118   {
119     ch = String[i];
120
121     if (ch >= 'A' && ch <= 'F')
122       ch += 32;
123
124     for (k = 0; k < 16 && ch != HexDigits[k]; k++);
125
126     if (k == 16)
127       return -1;
128
129     *MiniIndex = (*MiniIndex << 4) | k;
130   }
131
132   return 0;
133 }
134
135 static int FriendlyNameToMiniIndex(int *MiniIndex, char *String)
136 {
137   typedef DWORD (*GETADAPTERSADDRESSES)(ULONG Family,
138                                         DWORD Flags,
139                                         PVOID Reserved,
140                                         PIP_ADAPTER_ADDRESSES pAdapterAddresses,
141                                         PULONG pOutBufLen);
142   unsigned long BuffLen;
143   unsigned long Res;
144   IP_ADAPTER_ADDRESSES AdAddr[MAX_INTERFACES], *WalkerAddr;
145   char FriendlyName[MAX_INTERFACE_NAME_LEN];
146   HMODULE h;
147   GETADAPTERSADDRESSES pfGetAdaptersAddresses;
148   
149   h = LoadLibrary("iphlpapi.dll");
150
151   if (h == NULL)
152   {
153     fprintf(stderr, "LoadLibrary() = %08lx", GetLastError());
154     return -1;
155   }
156
157   pfGetAdaptersAddresses = (GETADAPTERSADDRESSES) GetProcAddress(h, "GetAdaptersAddresses");
158
159   if (pfGetAdaptersAddresses == NULL)
160   {
161     fprintf(stderr, "Unable to use adapter friendly name (GetProcAddress() = %08lx)\n", GetLastError());
162     return -1;
163   }
164   
165   BuffLen = sizeof (AdAddr);
166
167   Res = pfGetAdaptersAddresses(AF_INET, 0, NULL, AdAddr, &BuffLen);
168
169   if (Res != NO_ERROR)
170   {  
171     fprintf(stderr, "GetAdaptersAddresses() = %08lx", GetLastError());
172     return -1;
173   }
174
175   for (WalkerAddr = AdAddr; WalkerAddr != NULL; WalkerAddr = WalkerAddr->Next)
176   {
177     OLSR_PRINTF(5, "Index = %08x - ", (int)WalkerAddr->IfIndex);
178
179     wcstombs(FriendlyName, WalkerAddr->FriendlyName, MAX_INTERFACE_NAME_LEN); 
180
181     OLSR_PRINTF(5, "Friendly name = %s\n", FriendlyName);
182
183     if (strncmp(FriendlyName, String, MAX_INTERFACE_NAME_LEN) == 0)
184       break;
185   }
186
187   if (WalkerAddr == NULL)
188   {
189     fprintf(stderr, "No such interface: %s!\n", String);
190     return -1;
191   }
192
193   *MiniIndex = WalkerAddr->IfIndex & 255;
194 }
195
196 int GetIntInfo(struct InterfaceInfo *Info, char *Name)
197 {
198   int MiniIndex;
199   unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4];
200   MIB_IFTABLE *IfTable;
201   unsigned long BuffLen;
202   unsigned long Res;
203   int TabIdx;
204   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
205
206   if (olsr_cnf->ip_version == AF_INET6)
207   {
208     fprintf(stderr, "IPv6 not supported by GetIntInfo()!\n");
209     return -1;
210   }
211
212   if ((Name[0] != 'i' && Name[0] != 'I') ||
213       (Name[1] != 'f' && Name[1] != 'F'))
214   {
215     if (FriendlyNameToMiniIndex(&MiniIndex, Name) < 0)
216     {
217       fprintf(stderr, "No such interface: %s!\n", Name);
218       return -1;
219     }
220   }
221
222   else
223   {
224     if (IntNameToMiniIndex(&MiniIndex, Name) < 0)
225     {
226       fprintf(stderr, "No such interface: %s!\n", Name);
227       return -1;
228     }
229   }
230
231   IfTable = (MIB_IFTABLE *)Buff;
232
233   BuffLen = sizeof (Buff);
234
235   Res = GetIfTable(IfTable, &BuffLen, FALSE);
236
237   if (Res != NO_ERROR)
238   {
239     fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
240     return -1;
241   }
242
243   for (TabIdx = 0; TabIdx < (int)IfTable->dwNumEntries; TabIdx++)
244   {
245     OLSR_PRINTF(5, "Index = %08x\n", (int)IfTable->table[TabIdx].dwIndex);
246
247     if ((int)(IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
248       break;
249   }
250
251   if (TabIdx == (int)IfTable->dwNumEntries)
252   {
253     fprintf(stderr, "No such interface: %s!\n", Name);
254     return -1;
255   }
256     
257   Info->Index = IfTable->table[TabIdx].dwIndex;
258   Info->Mtu = (int)IfTable->table[TabIdx].dwMtu;
259
260   Info->Mtu -= (olsr_cnf->ip_version == AF_INET6) ?
261     UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
262
263   BuffLen = sizeof (AdInfo);
264
265   Res = GetAdaptersInfo(AdInfo, &BuffLen);
266
267   if (Res != NO_ERROR)
268   {
269     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(),
270             StrError(Res));
271     return -1;
272   }
273
274   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
275   {
276     OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
277
278     if ((int)(Walker->Index & 255) == MiniIndex)
279       break;
280   }
281
282   if (Walker == NULL)
283   {
284     fprintf(stderr, "No such interface: %s!\n", Name);
285     return -1;
286   }
287
288   inet_pton(AF_INET, Walker->IpAddressList.IpAddress.String, &Info->Addr);
289   inet_pton(AF_INET, Walker->IpAddressList.IpMask.String, &Info->Mask);
290
291   Info->Broad = Info->Addr | ~Info->Mask;
292
293   strcpy(Info->Guid, Walker->AdapterName);
294
295   if ((IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED &&
296       IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL) ||
297       Info->Addr == 0)
298   {
299     OLSR_PRINTF(3, "Interface %s not up!\n", Name);
300     return -1;
301   }
302
303   return 0;
304 }
305
306 #if !defined OID_802_11_CONFIGURATION
307 #define OID_802_11_CONFIGURATION 0x0d010211
308 #endif
309
310 #if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS
311 #define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
312 #endif
313
314 static int IsWireless(char *IntName)
315 {
316 #if !defined WINCE
317   struct InterfaceInfo Info;
318   char DevName[43];
319   HANDLE DevHand;
320   unsigned int ErrNo;
321   unsigned int Oid;
322   unsigned char OutBuff[100];
323   unsigned long OutBytes;
324
325   if (GetIntInfo(&Info, IntName) < 0)
326     return -1;
327
328   DevName[0] = '\\';
329   DevName[1] = '\\';
330   DevName[2] = '.';
331   DevName[3] = '\\';
332
333   strcpy(DevName + 4, Info.Guid);
334
335   OLSR_PRINTF(5, "Checking whether interface %s is wireless.\n", DevName);
336
337   DevHand = CreateFile(DevName, GENERIC_READ,
338                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
339                        FILE_ATTRIBUTE_NORMAL, NULL);
340
341   if (DevHand == INVALID_HANDLE_VALUE)
342   {
343     ErrNo = GetLastError();
344
345     OLSR_PRINTF(5, "CreateFile() = %08x, %s\n", ErrNo, StrError(ErrNo));
346     return -1;
347   }
348
349   Oid = OID_802_11_CONFIGURATION;
350
351   if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS,
352                        &Oid, sizeof (Oid),
353                        OutBuff, sizeof (OutBuff),
354                        &OutBytes, NULL))
355   {
356     ErrNo = GetLastError();
357
358     CloseHandle(DevHand);
359
360     if (ErrNo == ERROR_GEN_FAILURE)
361     {
362       OLSR_PRINTF(5, "OID not supported. Device probably not wireless.\n")
363       return 0;
364     }
365
366     OLSR_PRINTF(5, "DeviceIoControl() = %08x, %s\n", ErrNo, StrError(ErrNo))
367     return -1;
368   }
369
370   CloseHandle(DevHand);
371 #endif
372   return 1;
373 }
374
375 void ListInterfaces(void)
376 {
377   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
378   unsigned long AdInfoLen;
379   char IntName[5];
380   IP_ADDR_STRING *Walker2;
381   unsigned long Res;
382   int IsWlan;
383   
384   if (olsr_cnf->ip_version == AF_INET6)
385   {
386     fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n");
387     return;
388   }
389
390   AdInfoLen = sizeof (AdInfo);
391
392   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
393
394   if (Res == ERROR_NO_DATA)
395   {
396     printf("No interfaces detected.\n");
397     return;
398   }
399   
400   if (Res != NO_ERROR)
401   {
402     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
403     return;
404   }
405
406   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
407   {
408     OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index)
409
410     MiniIndexToIntName(IntName, Walker->Index);
411
412     printf("%s: ", IntName);
413
414     IsWlan = IsWireless(IntName);
415
416     if (IsWlan < 0)
417       printf("?");
418
419     else if (IsWlan == 0)
420       printf("-");
421
422     else
423       printf("+");
424
425     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
426          Walker2 = Walker2->Next)
427       printf(" %s", Walker2->IpAddress.String);
428
429     printf("\n");
430   }
431 }
432
433 void RemoveInterface(struct olsr_if *IntConf)
434 {
435   struct interface *Int, *Prev;
436
437   OLSR_PRINTF(1, "Removing interface %s.\n", IntConf->name)
438   
439   Int = IntConf->interf;
440
441   run_ifchg_cbs(Int, IFCHG_IF_ADD);
442
443   if (Int == ifnet)
444     ifnet = Int->int_next;
445
446   else
447   {
448     for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
449
450     Prev->int_next = Int->int_next;
451   }
452
453   if(COMP_IP(&olsr_cnf->main_addr, &Int->ip_addr))
454   {
455     if(ifnet == NULL)
456     {
457       memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
458       OLSR_PRINTF(1, "Removed last interface. Cleared main address.\n")
459     }
460
461     else
462     {
463       COPY_IP(&olsr_cnf->main_addr, &ifnet->ip_addr);
464       OLSR_PRINTF(1, "New main address: %s.\n", olsr_ip_to_string(&olsr_cnf->main_addr))
465     }
466   }
467
468   if (olsr_cnf->lq_level == 0)
469     {
470       olsr_remove_scheduler_event(&generate_hello, Int,
471                                   IntConf->cnf->hello_params.emission_interval,
472                                   0, NULL);
473
474       olsr_remove_scheduler_event(&generate_tc, Int,
475                                   IntConf->cnf->tc_params.emission_interval,
476                                   0, NULL);
477     }
478
479   else
480     {
481       olsr_remove_scheduler_event(&olsr_output_lq_hello, Int,
482                                   IntConf->cnf->hello_params.emission_interval,
483                                   0, NULL);
484
485       olsr_remove_scheduler_event(&olsr_output_lq_tc, Int,
486                                   IntConf->cnf->tc_params.emission_interval,
487                                   0, NULL);
488     }
489
490   olsr_remove_scheduler_event(&generate_mid, Int,
491                               IntConf->cnf->mid_params.emission_interval,
492                               0, NULL);
493
494   olsr_remove_scheduler_event(&generate_hna, Int,
495                               IntConf->cnf->hna_params.emission_interval,
496                               0, NULL);
497
498   net_remove_buffer(Int);
499
500   IntConf->configured = 0;
501   IntConf->interf = NULL;
502
503   closesocket(Int->olsr_socket);
504   remove_olsr_socket(Int->olsr_socket, &olsr_input);
505
506   free(Int->int_name);
507   free(Int);
508
509   if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
510   {
511     OLSR_PRINTF(1, "No more active interfaces - exiting.\n")
512     olsr_cnf->exit_value = EXIT_FAILURE;
513     CallSignalHandler();
514   }
515 }
516
517 int add_hemu_if(struct olsr_if *iface)
518 {
519   struct interface *ifp;
520   union olsr_ip_addr null_addr;
521   olsr_u32_t addr[4];
522
523   if(!iface->host_emul)
524     return -1;
525
526   ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
527
528   memset(ifp, 0, sizeof (struct interface));
529
530   iface->configured = OLSR_TRUE;
531   iface->interf = ifp;
532
533   ifp->is_hcif = OLSR_TRUE;
534   ifp->int_name = olsr_malloc(strlen("hcif01") + 1, "Interface update 3");
535   ifp->int_metric = 0;
536
537   strcpy(ifp->int_name, "hcif01");
538
539   OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name)
540
541   OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&iface->hemu_ip));
542
543   OLSR_PRINTF(1, "       Index:%d\n", iface->index);
544
545   OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
546
547   ifp->int_next = ifnet;
548   ifnet = ifp;
549
550   memset(&null_addr, 0, olsr_cnf->ipsize);
551   if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
552     {
553       COPY_IP(&olsr_cnf->main_addr, &iface->hemu_ip);
554       OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
555     }
556
557   /* setting the interfaces number*/
558   ifp->if_nr = iface->index;
559
560   ifp->int_mtu = OLSR_DEFAULT_MTU;
561
562   ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ?
563     UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
564
565   /* Set up buffer */
566   net_add_buffer(ifp);
567
568
569   if(olsr_cnf->ip_version == AF_INET)
570     {
571       struct sockaddr_in sin;
572
573       memset(&sin, 0, sizeof(sin));
574
575       sin.sin_family = AF_INET;
576       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
577       sin.sin_port = htons(10150);
578  
579      /* IP version 4 */
580       ifp->ip_addr.v4 = iface->hemu_ip.v4;
581
582       memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
583       
584       /*
585        *We create one socket for each interface and bind
586        *the socket to it. This to ensure that we can control
587        *on what interface the message is transmitted
588        */
589       
590       ifp->olsr_socket = gethemusocket(&sin);
591       
592       if (ifp->olsr_socket < 0)
593         {
594           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
595           exit(1);
596         }
597
598     }
599   else
600     {
601       /* IP version 6 */
602       memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
603
604 #if 0      
605       /*
606        *We create one socket for each interface and bind
607        *the socket to it. This to ensure that we can control
608        *on what interface the message is transmitted
609        */
610       
611       ifp->olsr_socket = gethcsocket6(&addrsock6, bufspace, ifp->int_name);
612       
613       join_mcast(ifp, ifp->olsr_socket);
614       
615       if (ifp->olsr_socket < 0)
616         {
617           fprintf(stderr, "Could not initialize socket... exiting!\n\n");
618           exit(1);
619         }
620       
621 #endif
622     }
623
624   /* Send IP as first 4/16 bytes on socket */
625   memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
626   addr[0] = htonl(addr[0]);
627   addr[1] = htonl(addr[1]);
628   addr[2] = htonl(addr[2]);
629   addr[3] = htonl(addr[3]);
630
631   if(send(ifp->olsr_socket, (char *)addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
632     {
633       fprintf(stderr, "Error sending IP!");
634     }  
635   
636   /* Register socket */
637   add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
638
639
640   if (olsr_cnf->lq_level == 0)
641     {
642       olsr_register_scheduler_event(&generate_hello, 
643                                     ifp, 
644                                     iface->cnf->hello_params.emission_interval, 
645                                     0, 
646                                     NULL);
647       olsr_register_scheduler_event(&generate_tc, 
648                                     ifp, 
649                                     iface->cnf->tc_params.emission_interval,
650                                     0, 
651                                     NULL);
652     }
653
654   else
655     {
656       olsr_register_scheduler_event(&olsr_output_lq_hello, 
657                                     ifp, 
658                                     iface->cnf->hello_params.emission_interval, 
659                                     0, 
660                                     NULL);
661       olsr_register_scheduler_event(&olsr_output_lq_tc, 
662                                     ifp, 
663                                     iface->cnf->tc_params.emission_interval,
664                                     0, 
665                                     NULL);
666     }
667
668   olsr_register_scheduler_event(&generate_mid, 
669                                 ifp, 
670                                 iface->cnf->mid_params.emission_interval,
671                                 0, 
672                                 NULL);
673   olsr_register_scheduler_event(&generate_hna, 
674                                 ifp, 
675                                 iface->cnf->hna_params.emission_interval,
676                                 0, 
677                                 NULL);
678
679   /* Recalculate max jitter */
680
681   if((olsr_cnf->max_jitter == 0) || 
682      ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
683     olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
684
685   /* Recalculate max topology hold time */
686   if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
687     olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
688
689   ifp->hello_etime = iface->cnf->hello_params.emission_interval;
690   ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
691   ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
692   ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
693   ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
694
695   return 1;
696 }
697
698 int chk_if_changed(struct olsr_if *IntConf)
699 {
700   struct interface *Int;
701   struct InterfaceInfo Info;
702   int Res;
703   int IsWlan;
704   union olsr_ip_addr OldVal, NewVal;
705   struct sockaddr_in *AddrIn;
706
707   if (olsr_cnf->ip_version == AF_INET6)
708   {
709     fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
710     return 0;
711   }
712
713 #ifdef DEBUG
714   OLSR_PRINTF(3, "Checking if %s is set down or changed\n", IntConf->name)
715 #endif
716
717   Int = IntConf->interf;
718
719   if (GetIntInfo(&Info, IntConf->name) < 0)
720   {
721     RemoveInterface(IntConf);
722     return 1;
723   }
724
725   Res = 0;
726
727   IsWlan = IsWireless(IntConf->name);
728
729   if (IsWlan < 0)
730     IsWlan = 1;
731
732   if (Int->is_wireless != IsWlan)
733   {
734     OLSR_PRINTF(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan)
735
736     Int->is_wireless = IsWlan;
737
738     if (IntConf->cnf->weight.fixed)
739       Int->int_metric = IntConf->cnf->weight.value;
740
741     else
742       Int->int_metric = IsWlan;
743
744     Res = 1;
745   }
746
747   if (Int->int_mtu != Info.Mtu)
748   {
749     OLSR_PRINTF(1, "\tMTU change: %d -> %d.\n", (int)Int->int_mtu,
750                 Info.Mtu);
751
752     Int->int_mtu = Info.Mtu;
753
754     net_remove_buffer(Int);
755     net_add_buffer(Int);
756
757     Res = 1;
758   }
759
760   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr.s_addr;
761   NewVal.v4 = Info.Addr;
762
763 #ifdef DEBUG
764   OLSR_PRINTF(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal))
765 #endif
766
767   if (NewVal.v4 != OldVal.v4)
768   {
769     OLSR_PRINTF(1, "\tAddress change.\n")
770     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
771     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
772
773     Int->ip_addr.v4 = NewVal.v4;
774
775     AddrIn = (struct sockaddr_in *)&Int->int_addr;
776
777     AddrIn->sin_family = AF_INET;
778     AddrIn->sin_port = 0;
779     AddrIn->sin_addr.s_addr = NewVal.v4;
780
781     if (olsr_cnf->main_addr.v4 == OldVal.v4)
782     {
783       OLSR_PRINTF(1, "\tMain address change.\n")
784
785       olsr_cnf->main_addr.v4 = NewVal.v4;
786     }
787
788     Res = 1;
789   }
790
791   else
792     OLSR_PRINTF(3, "\tNo address change.\n")
793
794   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr.s_addr;
795   NewVal.v4 = Info.Mask;
796
797 #ifdef DEBUG
798   OLSR_PRINTF(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal))
799 #endif
800
801   if (NewVal.v4 != OldVal.v4)
802   {
803     OLSR_PRINTF(1, "\tNetmask change.\n")
804     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
805     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
806
807     AddrIn = (struct sockaddr_in *)&Int->int_netmask;
808
809     AddrIn->sin_family = AF_INET;
810     AddrIn->sin_port = 0;
811     AddrIn->sin_addr.s_addr = NewVal.v4;
812
813     Res = 1;
814   }
815
816   else
817     OLSR_PRINTF(3, "\tNo netmask change.\n")
818
819   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr.s_addr;
820   NewVal.v4 = Info.Broad;
821
822 #ifdef DEBUG
823   OLSR_PRINTF(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal))
824 #endif
825
826   if (NewVal.v4 != OldVal.v4)
827   {
828     OLSR_PRINTF(1, "\tBroadcast address change.\n")
829     OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
830     OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
831
832     AddrIn = (struct sockaddr_in *)&Int->int_broadaddr;
833
834     AddrIn->sin_family = AF_INET;
835     AddrIn->sin_port = 0;
836     AddrIn->sin_addr.s_addr = NewVal.v4;
837
838     Res = 1;
839   }
840
841   else
842     OLSR_PRINTF(3, "\tNo broadcast address change.\n")
843
844   if (Res != 0)
845     run_ifchg_cbs(Int, IFCHG_IF_UPDATE);
846
847   return Res;
848 }
849
850 int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
851 {
852   struct InterfaceInfo Info;
853   struct interface *New;
854   union olsr_ip_addr NullAddr;
855   unsigned int AddrSockAddr;
856   int IsWlan;
857   struct sockaddr_in *AddrIn;
858   
859   if (olsr_cnf->ip_version == AF_INET6)
860   {
861     fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
862     return 0;
863   }
864
865   if (GetIntInfo(&Info, IntConf->name) < 0)
866     return 0;
867
868   New = olsr_malloc(sizeof (struct interface), "Interface 1");
869   New->gen_properties = NULL;
870
871   AddrIn = (struct sockaddr_in *)&New->int_addr;
872
873   AddrIn->sin_family = AF_INET;
874   AddrIn->sin_port = 0;
875   AddrIn->sin_addr.s_addr = Info.Addr;
876
877   AddrIn = (struct sockaddr_in *)&New->int_netmask;
878
879   AddrIn->sin_family = AF_INET;
880   AddrIn->sin_port = 0;
881   AddrIn->sin_addr.s_addr = Info.Mask;
882
883   AddrIn = (struct sockaddr_in *)&New->int_broadaddr;
884
885   AddrIn->sin_family = AF_INET;
886   AddrIn->sin_port = 0;
887   AddrIn->sin_addr.s_addr = Info.Broad;
888
889   if (IntConf->cnf->ipv4_broadcast.v4 != 0)
890     AddrIn->sin_addr.s_addr = IntConf->cnf->ipv4_broadcast.v4;
891
892   New->int_flags = 0;
893
894   New->is_hcif = OLSR_FALSE;
895
896   New->int_mtu = Info.Mtu;
897
898   New->int_name = olsr_malloc(strlen (IntConf->name) + 1, "Interface 2");
899   strcpy(New->int_name, IntConf->name);
900
901   New->if_nr = IntConf->index;
902
903   IsWlan = IsWireless(IntConf->name);
904
905   if (IsWlan < 0)
906     IsWlan = 1;
907
908   New->is_wireless = IsWlan;
909
910   if (IntConf->cnf->weight.fixed)
911     New->int_metric = IntConf->cnf->weight.value;
912
913   else
914     New->int_metric = IsWlan;
915
916   New->olsr_seqnum = random() & 0xffff;
917     
918   OLSR_PRINTF(1, "\tInterface %s set up for use with index %d\n\n",
919               IntConf->name, New->if_nr)
920       
921   OLSR_PRINTF(1, "\tMTU: %d\n", New->int_mtu)
922   OLSR_PRINTF(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr))
923   OLSR_PRINTF(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask))
924   OLSR_PRINTF(1, "\tBroadcast address: %s\n",
925               sockaddr_to_string(&New->int_broadaddr))
926
927   New->ip_addr.v4 =
928     ((struct sockaddr_in *)&New->int_addr)->sin_addr.s_addr;
929       
930   New->if_index = Info.Index;
931
932   OLSR_PRINTF(3, "\tKernel index: %08x\n", New->if_index)
933
934   AddrSockAddr = addrsock.sin_addr.s_addr;
935   addrsock.sin_addr.s_addr = New->ip_addr.v4;
936
937   New->olsr_socket = getsocket((struct sockaddr *)&addrsock,
938                                127 * 1024, New->int_name);
939       
940   addrsock.sin_addr.s_addr = AddrSockAddr;
941
942   if (New->olsr_socket < 0)
943   {
944     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
945     exit(1);
946   }
947
948   add_olsr_socket(New->olsr_socket, &olsr_input);
949
950   New->int_next = ifnet;
951   ifnet = New;
952
953   IntConf->interf = New;
954   IntConf->configured = 1;
955
956   memset(&NullAddr, 0, olsr_cnf->ipsize);
957   
958   if(COMP_IP(&NullAddr, &olsr_cnf->main_addr))
959   {
960     COPY_IP(&olsr_cnf->main_addr, &New->ip_addr);
961     OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
962   }
963
964   net_add_buffer(New);
965
966   if (olsr_cnf->lq_level == 0)
967   {
968     olsr_register_scheduler_event(&generate_hello, New,
969                                   IntConf->cnf->hello_params.emission_interval,
970                                   0, NULL);
971
972     olsr_register_scheduler_event(&generate_tc, New,
973                                   IntConf->cnf->tc_params.emission_interval,
974                                   0, NULL);
975   }
976
977   else
978   {
979     olsr_register_scheduler_event(&olsr_output_lq_hello, New,
980                                   IntConf->cnf->hello_params.emission_interval,
981                                   0, NULL);
982
983     olsr_register_scheduler_event(&olsr_output_lq_tc, New,
984                                   IntConf->cnf->tc_params.emission_interval,
985                                   0, NULL);
986   }
987
988   olsr_register_scheduler_event(&generate_mid, New,
989                                 IntConf->cnf->mid_params.emission_interval,
990                                 0, NULL);
991
992   olsr_register_scheduler_event(&generate_hna, New,
993                                 IntConf->cnf->hna_params.emission_interval,
994                                 0, NULL);
995
996   if(olsr_cnf->max_jitter == 0 ||
997      IntConf->cnf->hello_params.emission_interval / 4 < olsr_cnf->max_jitter)
998     olsr_cnf->max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
999
1000   if(olsr_cnf->max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
1001     olsr_cnf->max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
1002
1003   New->hello_etime = IntConf->cnf->hello_params.emission_interval;
1004
1005   New->valtimes.hello = double_to_me(IntConf->cnf->hello_params.validity_time);
1006   New->valtimes.tc = double_to_me(IntConf->cnf->tc_params.validity_time);
1007   New->valtimes.mid = double_to_me(IntConf->cnf->mid_params.validity_time);
1008   New->valtimes.hna = double_to_me(IntConf->cnf->hna_params.validity_time);
1009
1010   run_ifchg_cbs(New, IFCHG_IF_ADD);
1011
1012   return 1;
1013 }
1014
1015 void check_interface_updates(void *dummy)
1016 {
1017   struct olsr_if *IntConf;
1018
1019 #ifdef DEBUG
1020   OLSR_PRINTF(3, "Checking for updates in the interface set\n")
1021 #endif
1022
1023   for(IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next)
1024   {
1025     if(IntConf->host_emul)
1026       continue;
1027       
1028     if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
1029       continue;
1030  
1031     if(IntConf->configured)    
1032       chk_if_changed(IntConf);
1033
1034     else
1035       chk_if_up(IntConf, 3);
1036   }
1037 }