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