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