62e0bad759614088c3da225e3329f7e55ccc2cd4
[olsrd.git] / src / win32 / ifnet.c
1 /* 
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
4  *
5  * Derived from its Linux counterpart.
6  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
7  *
8  * This file is part of the olsr.org OLSR daemon.
9  *
10  * olsr.org is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * olsr.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with olsr.org; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * $Id: ifnet.c,v 1.6 2004/10/19 21:44:56 tlopatic Exp $
25  *
26  */
27
28 #include "../interfaces.h"
29 #include "../olsr.h"
30 #include "../net.h"
31 #include "../parser.h"
32 #include "../socket_parser.h"
33 #include "../defs.h"
34 #include "../net_os.h"
35 #include "../ifnet.h"
36 #include "../generate_msg.h"
37 #include "../scheduler.h"
38 #include "../mantissa.h"
39
40 #include <iphlpapi.h>
41 #include <iprtrmib.h>
42
43 void WinSockPError(char *);
44 char *StrError(unsigned int ErrNo);
45 int inet_pton(int af, char *src, void *dst);
46
47 #define MAX_INTERFACES 25
48
49 int __stdcall SignalHandler(unsigned long Signal);
50
51 static unsigned long __stdcall SignalHandlerWrapper(void *Dummy)
52 {
53   SignalHandler(0);
54   return 0;
55 }
56
57 static void CallSignalHandler(void)
58 {
59   unsigned long ThreadId;
60
61   CreateThread(NULL, 0, SignalHandlerWrapper, NULL, 0, &ThreadId);
62 }
63
64 static void MiniIndexToIntName(char *String, int MiniIndex)
65 {
66   char *HexDigits = "0123456789abcdef";
67
68   String[0] = 'i';
69   String[1] = 'f';
70
71   String[2] = HexDigits[(MiniIndex >> 4) & 15];
72   String[3] = HexDigits[MiniIndex & 15];
73
74   String[4] = 0;
75 }
76
77 static int IntNameToMiniIndex(int *MiniIndex, char *String)
78 {
79   char *HexDigits = "0123456789abcdef";
80   int i, k;
81   char ch;
82
83   if ((String[0] != 'i' && String[0] != 'I') ||
84       (String[1] != 'f' && String[1] != 'F'))
85     return -1;
86
87   *MiniIndex = 0;
88
89   for (i = 2; i < 4; i++)
90   {
91     ch = String[i];
92
93     if (ch >= 'A' && ch <= 'F')
94       ch += 32;
95
96     for (k = 0; k < 16 && ch != HexDigits[k]; k++);
97
98     if (k == 16)
99       return -1;
100
101     *MiniIndex = (*MiniIndex << 4) | k;
102   }
103
104   return 0;
105 }
106
107 static int MiniIndexToGuid(char *Guid, int MiniIndex)
108 {
109   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
110   unsigned long AdInfoLen;
111   unsigned long Res;
112   
113   if (olsr_cnf->ip_version == AF_INET6)
114   {
115     fprintf(stderr, "IPv6 not supported by MiniIndexToGuid()!\n");
116     return -1;
117   }
118
119   AdInfoLen = sizeof (AdInfo);
120
121   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
122
123   if (Res != NO_ERROR)
124   {
125     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(),
126             StrError(Res));
127     return -1;
128   }
129
130   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
131   {
132     olsr_printf(5, "Index = %08x\n", Walker->Index);
133
134     if ((Walker->Index & 255) == MiniIndex)
135       break;
136   }
137
138   if (Walker != NULL)
139   {
140     olsr_printf(5, "Found interface.\n");
141
142     strcpy(Guid, Walker->AdapterName);
143     return 0;
144   }
145
146   olsr_printf(5, "Cannot map mini index %02x to an adapter GUID.\n",
147               MiniIndex);
148   return -1;
149 }
150
151 static int AddrToIndex(int *Index, unsigned int Addr)
152 {
153   unsigned int IntAddr;
154   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
155   unsigned long AdInfoLen;
156   IP_ADDR_STRING *Walker2;
157   unsigned long Res;
158   
159   olsr_printf(5, "AddrToIndex(%08x)\n", Addr);
160
161   if (olsr_cnf->ip_version == AF_INET6)
162   {
163     fprintf(stderr, "IPv6 not supported by AddrToIndex()!\n");
164     return -1;
165   }
166
167   AdInfoLen = sizeof (AdInfo);
168
169   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
170
171   if (Res != NO_ERROR)
172   {
173     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
174     return -1;
175   }
176
177   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
178   {
179     olsr_printf(5, "Index = %08x\n", Walker->Index);
180
181     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
182          Walker2 = Walker2->Next)
183     {
184       inet_pton(AF_INET, Walker2->IpAddress.String, &IntAddr);
185
186       olsr_printf(5, "\tIP address = %08x\n", IntAddr);
187
188       if (Addr == IntAddr)
189       {
190         olsr_printf(5, "Found interface.\n");
191         *Index = Walker->Index;
192         return 0;
193       }
194     }
195   }
196
197   olsr_printf(5, "Cannot map IP address %08x to an adapter index.\n", Addr);
198   return -1;
199 }
200
201 #if !defined OID_802_11_CONFIGURATION
202 #define OID_802_11_CONFIGURATION 0x0d010211
203 #endif
204
205 #if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS
206 #define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
207 #endif
208
209 static int IsWireless(char *IntName)
210 {
211   int MiniIndex;
212   char DevName[43];
213   HANDLE DevHand;
214   unsigned int ErrNo;
215   unsigned int Oid;
216   unsigned char OutBuff[100];
217   unsigned long OutBytes;
218
219   if (IntNameToMiniIndex(&MiniIndex, IntName) < 0)
220     return -1;
221
222   DevName[0] = '\\';
223   DevName[1] = '\\';
224   DevName[2] = '.';
225   DevName[3] = '\\';
226
227   if (MiniIndexToGuid(DevName + 4, MiniIndex) < 0)
228     return -1;
229
230   olsr_printf(5, "Checking whether interface %s is wireless.\n", DevName);
231
232   DevHand = CreateFile(DevName, GENERIC_READ,
233                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
234                        FILE_ATTRIBUTE_NORMAL, NULL);
235
236   if (DevHand == INVALID_HANDLE_VALUE)
237   {
238     ErrNo = GetLastError();
239
240     olsr_printf(5, "CreateFile() = %08lx, %s\n", ErrNo, StrError(ErrNo));
241     return -1;
242   }
243
244   Oid = OID_802_11_CONFIGURATION;
245
246   if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS,
247                        &Oid, sizeof (Oid),
248                        OutBuff, sizeof (OutBuff),
249                        &OutBytes, NULL))
250   {
251     ErrNo = GetLastError();
252
253     CloseHandle(DevHand);
254
255     if (ErrNo == ERROR_GEN_FAILURE)
256     {
257       olsr_printf(5, "OID not supported. Device probably not wireless.\n");
258       return 0;
259     }
260
261     olsr_printf(5, "DeviceIoControl() = %08lx, %s\n", ErrNo, StrError(ErrNo));
262     return -1;
263   }
264
265   CloseHandle(DevHand);
266   return 1;
267 }
268
269 void ListInterfaces(void)
270 {
271   IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
272   unsigned long AdInfoLen;
273   char IntName[5];
274   IP_ADDR_STRING *Walker2;
275   unsigned long Res;
276   int IsWlan;
277   
278   if (olsr_cnf->ip_version == AF_INET6)
279   {
280     fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n");
281     return;
282   }
283
284   AdInfoLen = sizeof (AdInfo);
285
286   Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
287
288   if (Res == ERROR_NO_DATA)
289   {
290     printf("No interfaces detected.\n");
291     return;
292   }
293   
294   if (Res != NO_ERROR)
295   {
296     fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
297     return;
298   }
299
300   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
301   {
302     olsr_printf(5, "Index = %08x\n", Walker->Index);
303
304     MiniIndexToIntName(IntName, Walker->Index);
305
306     printf("%s: ", IntName);
307
308     IsWlan = IsWireless(IntName);
309
310     if (IsWlan < 0)
311       printf("?");
312
313     else if (IsWlan == 0)
314       printf("-");
315
316     else
317       printf("+");
318
319     for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
320          Walker2 = Walker2->Next)
321       printf(" %s", Walker2->IpAddress.String);
322
323     printf("\n");
324   }
325 }
326
327 int InterfaceEntry(MIB_IFROW *IntPara, int *Index, struct olsr_if *IntConf)
328 {
329   int MiniIndex;
330   unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4];
331   MIB_IFTABLE *IfTable;
332   unsigned long BuffLen;
333   unsigned long Res;
334   int TabIdx;
335
336   if (olsr_cnf->ip_version == AF_INET6)
337   {
338     fprintf(stderr, "IPv6 not supported by AdapterInfo()!\n");
339     return -1;
340   }
341
342   if (IntNameToMiniIndex(&MiniIndex, IntConf->name) < 0)
343   {
344     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
345     return -1;
346   }
347
348   IfTable = (MIB_IFTABLE *)Buff;
349
350   BuffLen = sizeof (Buff);
351
352   Res = GetIfTable(IfTable, &BuffLen, FALSE);
353
354   if (Res != NO_ERROR)
355   {
356     fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
357     return -1;
358   }
359
360   for (TabIdx = 0; TabIdx < IfTable->dwNumEntries; TabIdx++)
361   {
362     olsr_printf(5, "Index = %08x\n", IfTable->table[TabIdx].dwIndex);
363
364     if ((IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
365       break;
366   }
367
368   if (TabIdx == IfTable->dwNumEntries)
369   {
370     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
371     return -1;
372   }
373     
374   *Index = IfTable->table[TabIdx].dwIndex;
375
376   memcpy(IntPara, &IfTable->table[TabIdx], sizeof (MIB_IFROW));
377   return 0;
378 }
379
380 int InterfaceInfo(INTERFACE_INFO *IntPara, int *Index, struct olsr_if *IntConf)
381 {
382   int MiniIndex;
383   int Sock;
384   INTERFACE_INFO IntInfo[25];
385   long Num;
386   int WsIdx;
387   int CandIndex;
388
389   if (IntNameToMiniIndex(&MiniIndex, IntConf->name) < 0)
390   {
391     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
392     return -1;
393   }
394
395   Sock = socket(olsr_cnf->ip_version, SOCK_STREAM, IPPROTO_TCP);
396
397   if (Sock < 0)
398   {
399     WinSockPError("socket()");
400     return -1;
401   }
402
403   if (WSAIoctl(Sock, SIO_GET_INTERFACE_LIST, NULL, 0,
404                IntInfo, sizeof (IntInfo), &Num, NULL, NULL) < 0)
405   {
406     WinSockPError("WSAIoctl(SIO_GET_INTERFACE_LIST)");
407     closesocket(Sock);
408     return -1;
409   }
410
411   closesocket(Sock);
412
413   Num /= sizeof (INTERFACE_INFO);
414
415   olsr_printf(5, "%s:\n", IntConf->name);
416
417   for (WsIdx = 0; WsIdx < Num; WsIdx++)
418   {
419     if (AddrToIndex(&CandIndex,
420                     IntInfo[WsIdx].iiAddress.AddressIn.sin_addr.s_addr) < 0)
421       continue;
422
423     if ((CandIndex & 255) == MiniIndex)
424       break;
425   }
426
427   if (WsIdx == Num)
428   {
429     fprintf(stderr, "No such interface: %s!\n", IntConf->name);
430     return -1;
431   }
432     
433   *Index = CandIndex;
434
435   olsr_printf(5, "\tIndex: %08x\n", *Index);
436
437   olsr_printf(5, "\tFlags: %08x\n", IntInfo[WsIdx].iiFlags);
438
439   if ((IntInfo[WsIdx].iiFlags & IFF_UP) == 0)
440   {
441     olsr_printf(1, "\tInterface not up - skipping it...\n");
442     return -1;
443   }
444
445   if (olsr_cnf->ip_version == AF_INET &&
446       (IntInfo[WsIdx].iiFlags & IFF_BROADCAST) == 0)
447   {
448     olsr_printf(1, "\tNo broadcast - skipping it...\n");
449     return -1;
450   }
451
452   if ((IntInfo[WsIdx].iiFlags & IFF_LOOPBACK) != 0)
453   {
454     olsr_printf(1, "\tThis is a loopback interface - skipping it...\n");
455     return -1;
456   }
457
458   // Windows seems to always return 255.255.255.255 as broadcast
459   // address, so I've tried using (address | ~netmask).
460
461   {
462     struct sockaddr_in *sin_a, *sin_n, *sin_b;
463     unsigned int a, n, b;
464
465     sin_a = (struct sockaddr_in *)&IntInfo[WsIdx].iiAddress;
466     sin_n = (struct sockaddr_in *)&IntInfo[WsIdx].iiNetmask;
467     sin_b = (struct sockaddr_in *)&IntInfo[WsIdx].iiBroadcastAddress;
468
469     a = sin_a->sin_addr.s_addr;
470     n = sin_n->sin_addr.s_addr;
471     b = sin_b->sin_addr.s_addr =
472       sin_a->sin_addr.s_addr | ~sin_n->sin_addr.s_addr;
473   }
474
475   memcpy(IntPara, &IntInfo[WsIdx], sizeof (INTERFACE_INFO));
476   return 0;
477 }
478
479 void RemoveInterface(struct olsr_if *IntConf)
480 {
481   struct interface *Int, *Prev;
482   struct ifchgf *Walker;
483
484   olsr_printf(1, "Removing interface %s.\n", IntConf->name);
485   
486   Int = IntConf->interf;
487
488   for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
489     Walker->function(Int, IFCHG_IF_REMOVE);
490
491   if (Int == ifnet)
492     ifnet = Int->int_next;
493
494   else
495   {
496     for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
497
498     Prev->int_next = Int->int_next;
499   }
500
501   if(COMP_IP(&main_addr, &Int->ip_addr))
502   {
503     if(ifnet == NULL)
504     {
505       memset(&main_addr, 0, ipsize);
506       olsr_printf(1, "Removed last interface. Cleared main address.\n");
507     }
508
509     else
510     {
511       COPY_IP(&main_addr, &ifnet->ip_addr);
512       olsr_printf(1, "New main address: %s.\n", olsr_ip_to_string(&main_addr));
513     }
514   }
515
516   olsr_remove_scheduler_event(&generate_hello, Int,
517                               IntConf->cnf->hello_params.emission_interval,
518                               0, NULL);
519
520   olsr_remove_scheduler_event(&generate_tc, Int,
521                               IntConf->cnf->tc_params.emission_interval,
522                               0, NULL);
523
524   olsr_remove_scheduler_event(&generate_mid, Int,
525                               IntConf->cnf->mid_params.emission_interval,
526                               0, NULL);
527
528   olsr_remove_scheduler_event(&generate_hna, Int,
529                               IntConf->cnf->hna_params.emission_interval,
530                               0, NULL);
531
532   net_remove_buffer(Int);
533
534   IntConf->configured = 0;
535   IntConf->interf = NULL;
536
537   closesocket(Int->olsr_socket);
538   remove_olsr_socket(Int->olsr_socket, &olsr_input);
539
540   free(Int->int_name);
541   free(Int);
542
543   if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
544   {
545     olsr_printf(1, "No more active interfaces - exiting.\n");
546     exit_value = EXIT_FAILURE;
547     CallSignalHandler();
548   }
549 }
550
551 int chk_if_changed(struct olsr_if *IntConf)
552 {
553   struct interface *Int;
554   INTERFACE_INFO IntInfo;
555   MIB_IFROW IntRow;
556   int Index;
557   int Res;
558   union olsr_ip_addr OldVal, NewVal;
559   struct ifchgf *Walker;
560   int IsWlan;
561
562   if (olsr_cnf->ip_version == AF_INET6)
563   {
564     fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
565     return 0;
566   }
567
568 #ifdef DEBUG
569   olsr_printf(3, "Checking if %s is set down or changed\n", IntConf->name);
570 #endif
571
572   Int = IntConf->interf;
573
574   if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
575       InterfaceEntry(&IntRow, &Index, IntConf))
576   {
577     RemoveInterface(IntConf);
578     return 1;
579   }
580
581   Res = 0;
582
583   IsWlan = IsWireless(IntConf->name);
584
585   if (IsWlan < 0)
586     IsWlan = 1;
587
588   if (Int->is_wireless != IsWlan)
589   {
590     olsr_printf(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan);
591
592     Int->is_wireless = IsWlan;
593     Int->int_metric = IsWlan;
594
595     Res = 1;
596   }
597
598   if (Int->int_mtu != IntRow.dwMtu)
599   {
600     olsr_printf(1, "\tMTU change: %d -> %d.\n", Int->int_mtu, IntRow.dwMtu);
601
602     Int->int_mtu = IntRow.dwMtu;
603
604     net_remove_buffer(Int);
605     net_add_buffer(Int);
606
607     Res = 1;
608   }
609
610   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr.s_addr;
611   NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiAddress)->sin_addr.s_addr;
612
613 #ifdef DEBUG
614   olsr_printf(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal));
615 #endif
616
617   if (NewVal.v4 != OldVal.v4)
618   {
619     olsr_printf(1, "\tAddress change.\n");
620     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
621     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
622
623     Int->ip_addr.v4 = NewVal.v4;
624
625     memcpy(&Int->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
626
627     if (main_addr.v4 == OldVal.v4)
628     {
629       olsr_printf(1, "\tMain address change.\n");
630
631       main_addr.v4 = NewVal.v4;
632     }
633
634     Res = 1;
635   }
636
637   else
638     olsr_printf(3, "\tNo address change.\n");
639
640   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr.s_addr;
641   NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiNetmask)->sin_addr.s_addr;
642
643 #ifdef DEBUG
644   olsr_printf(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal));
645 #endif
646
647   if(NewVal.v4 != OldVal.v4)
648   {
649     olsr_printf(1, "\tNetmask change.\n");
650     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
651     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
652
653     memcpy(&Int->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
654
655     Res = 1;
656   }
657
658   else
659     olsr_printf(3, "\tNo netmask change.\n");
660
661   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr.s_addr;
662   NewVal.v4 =
663     ((struct sockaddr_in *)&IntInfo.iiBroadcastAddress)->sin_addr.s_addr;
664
665 #ifdef DEBUG
666   olsr_printf(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal));
667 #endif
668
669   if(NewVal.v4 != OldVal.v4)
670   {
671     olsr_printf(1, "\tBroadcast address change.\n");
672     olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
673     olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
674
675     memcpy(&Int->int_broadaddr, &IntInfo.iiBroadcastAddress,
676            sizeof (struct sockaddr_in));
677
678     Res = 1;
679   }
680
681   else
682     olsr_printf(3, "\tNo broadcast address change.\n");
683
684   if (Res != 0)
685     for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
686       Walker->function(Int, IFCHG_IF_UPDATE);
687
688   return Res;
689 }
690
691 int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
692 {
693   struct interface *New;
694   union olsr_ip_addr NullAddr;
695   INTERFACE_INFO IntInfo;
696   MIB_IFROW IntRow;
697   int Index;
698   unsigned int AddrSockAddr;
699   struct ifchgf *Walker;
700   int IsWlan;
701   
702   if (olsr_cnf->ip_version == AF_INET6)
703   {
704     fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
705     return 0;
706   }
707
708   if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
709       InterfaceEntry(&IntRow, &Index, IntConf) < 0)
710     return 0;
711
712   New = olsr_malloc(sizeof (struct interface), "Interface 1");
713       
714   memcpy(&New->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
715
716   memcpy(&New->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
717
718   memcpy(&New->int_broadaddr, &IntInfo.iiBroadcastAddress,
719          sizeof (struct sockaddr_in));
720
721   if (IntConf->cnf->ipv4_broadcast.v4 != 0)
722     ((struct sockaddr_in *)&New->int_broadaddr)->sin_addr.s_addr =
723       IntConf->cnf->ipv4_broadcast.v4;
724
725   New->int_flags = IntInfo.iiFlags;
726
727   New->int_mtu = IntRow.dwMtu;
728
729   New->int_name = olsr_malloc(strlen (IntConf->name) + 1, "Interface 2");
730   strcpy(New->int_name, IntConf->name);
731
732   New->if_nr = IntConf->index;
733
734   IsWlan = IsWireless(IntConf->name);
735
736   if (IsWlan < 0)
737     IsWlan = 1;
738
739   New->is_wireless = IsWlan;
740   New->int_metric = IsWlan;
741
742   New->olsr_seqnum = random() & 0xffff;
743     
744   olsr_printf(1, "\tInterface %s set up for use with index %d\n\n",
745               IntConf->name, New->if_nr);
746       
747   olsr_printf(1, "\tMTU: %d\n", New->int_mtu);
748   olsr_printf(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr));
749   olsr_printf(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask));
750   olsr_printf(1, "\tBroadcast address: %s\n",
751               sockaddr_to_string(&New->int_broadaddr));
752
753   New->ip_addr.v4 =
754     ((struct sockaddr_in *)&New->int_addr)->sin_addr.s_addr;
755       
756   New->if_index = Index;
757
758   olsr_printf(3, "\tKernel index: %08x\n", New->if_index);
759
760   AddrSockAddr = addrsock.sin_addr.s_addr;
761   addrsock.sin_addr.s_addr = New->ip_addr.v4;
762
763   New->olsr_socket = getsocket((struct sockaddr *)&addrsock,
764                                127 * 1024, New->int_name);
765       
766   addrsock.sin_addr.s_addr = AddrSockAddr;
767
768   if (New->olsr_socket < 0)
769   {
770     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
771     exit(1);
772   }
773
774   add_olsr_socket(New->olsr_socket, &olsr_input);
775
776   New->int_next = ifnet;
777   ifnet = New;
778
779   IntConf->interf = New;
780   IntConf->configured = 1;
781
782   memset(&NullAddr, 0, ipsize);
783   
784   if(COMP_IP(&NullAddr, &main_addr))
785   {
786     COPY_IP(&main_addr, &New->ip_addr);
787
788     olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
789   }
790
791   net_add_buffer(New);
792
793   olsr_register_scheduler_event(&generate_hello, New,
794                                 IntConf->cnf->hello_params.emission_interval,
795                                 0, NULL);
796
797   olsr_register_scheduler_event(&generate_tc, New,
798                                 IntConf->cnf->tc_params.emission_interval,
799                                 0, NULL);
800
801   olsr_register_scheduler_event(&generate_mid, New,
802                                 IntConf->cnf->mid_params.emission_interval,
803                                 0, NULL);
804
805   olsr_register_scheduler_event(&generate_hna, New,
806                                 IntConf->cnf->hna_params.emission_interval,
807                                 0, NULL);
808
809   if(max_jitter == 0 ||
810      IntConf->cnf->hello_params.emission_interval / 4 < max_jitter)
811     max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
812
813   if(max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
814     max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
815
816   New->hello_etime =
817     double_to_me(IntConf->cnf->hello_params.emission_interval);
818
819   New->valtimes.hello = double_to_me(IntConf->cnf->hello_params.validity_time);
820   New->valtimes.tc = double_to_me(IntConf->cnf->tc_params.validity_time);
821   New->valtimes.mid = double_to_me(IntConf->cnf->mid_params.validity_time);
822   New->valtimes.hna = double_to_me(IntConf->cnf->hna_params.validity_time);
823
824   for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
825     Walker->function(New, IFCHG_IF_ADD);
826
827   return 1;
828 }
829
830 void check_interface_updates(void *dummy)
831 {
832   struct olsr_if *IntConf;
833
834 #ifdef DEBUG
835   olsr_printf(3, "Checking for updates in the interface set\n");
836 #endif
837
838   for(IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next)
839   {
840     if(IntConf->configured)    
841       chk_if_changed(IntConf);
842
843     else
844       chk_if_up(IntConf, 3);
845   }
846 }