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