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