3 * The olsr.org Optimized Link-State Routing daemon (olsrd)
4 * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
46 #include "interfaces.h"
52 #include "generate_msg.h"
53 #include "scheduler.h"
55 #include "lq_packet.h"
57 #include "olsr_random.h"
62 #include <arpa/inet.h>
64 #define BUFSPACE (127*1024) /* max. input buffer size to request */
66 struct MibIpInterfaceRow {
68 ULONG64 InterfaceLuid;
70 ULONG MaxReassemblySize;
71 ULONG64 InterfaceIdentifier;
72 ULONG MinRouterAdvertisementInterval;
73 ULONG MaxRouterAdvertisementInterval;
74 BOOLEAN AdvertisingEnabled;
75 BOOLEAN ForwardingEnabled;
77 BOOLEAN WeakHostReceive;
78 BOOLEAN UseAutomaticMetric;
79 BOOLEAN UseNeighborUnreachabilityDetection;
80 BOOLEAN ManagedAddressConfigurationSupported;
81 BOOLEAN OtherStatefulConfigurationSupported;
82 BOOLEAN AdvertiseDefaultRoute;
83 INT RouterDiscoveryBehavior;
85 ULONG BaseReachableTime;
87 ULONG PathMtuDiscoveryTimeout;
88 INT LinkLocalAddressBehavior;
89 ULONG LinkLocalAddressTimeout;
90 ULONG ZoneIndices[16];
91 ULONG SitePrefixLength;
95 BOOLEAN SupportsWakeUpPatterns;
96 BOOLEAN SupportsNeighborDiscovery;
97 BOOLEAN SupportsRouterDiscovery;
101 BOOLEAN DisableDefaultRoutes;
104 typedef DWORD(__stdcall * GETIPINTERFACEENTRY) (struct MibIpInterfaceRow * Row);
106 typedef DWORD(__stdcall * GETADAPTERSADDRESSES) (ULONG Family, DWORD Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses,
109 struct InterfaceInfo {
119 void WinSockPError(char *);
120 char *StrError(unsigned int ErrNo);
122 void ListInterfaces(void);
123 int GetIntInfo(struct InterfaceInfo *Info, char *Name);
125 #define MAX_INTERFACES 100
128 MiniIndexToIntName(char *String, int MiniIndex)
130 const char *HexDigits = "0123456789abcdef";
135 String[2] = HexDigits[(MiniIndex >> 4) & 15];
136 String[3] = HexDigits[MiniIndex & 15];
142 IntNameToMiniIndex(int *MiniIndex, char *String)
144 const char *HexDigits = "0123456789abcdef";
148 if ((String[0] != 'i' && String[0] != 'I') || (String[1] != 'f' && String[1] != 'F'))
153 for (i = 2; i < 4; i++) {
156 if (ch >= 'A' && ch <= 'F')
159 for (k = 0; k < 16 && ch != HexDigits[k]; k++);
164 *MiniIndex = (*MiniIndex << 4) | k;
171 FriendlyNameToMiniIndex(int *MiniIndex, char *String)
173 unsigned long BuffLen;
175 IP_ADAPTER_ADDRESSES AdAddr[MAX_INTERFACES], *WalkerAddr;
176 char FriendlyName[MAX_INTERFACE_NAME_LEN];
178 GETADAPTERSADDRESSES pfGetAdaptersAddresses;
180 h = LoadLibrary("iphlpapi.dll");
183 fprintf(stderr, "LoadLibrary() = %08lx", GetLastError());
187 pfGetAdaptersAddresses = (GETADAPTERSADDRESSES) GetProcAddress(h, "GetAdaptersAddresses");
189 if (pfGetAdaptersAddresses == NULL) {
190 fprintf(stderr, "Unable to use adapter friendly name (GetProcAddress() = %08lx)\n", GetLastError());
194 BuffLen = sizeof(AdAddr);
196 Res = pfGetAdaptersAddresses(AF_INET, 0, NULL, AdAddr, &BuffLen);
198 if (Res != NO_ERROR) {
199 fprintf(stderr, "GetAdaptersAddresses() = %08lx", GetLastError());
203 for (WalkerAddr = AdAddr; WalkerAddr != NULL; WalkerAddr = WalkerAddr->Next) {
204 OLSR_PRINTF(5, "Index = %08x - ", (int)WalkerAddr->IfIndex);
206 wcstombs(FriendlyName, WalkerAddr->FriendlyName, MAX_INTERFACE_NAME_LEN);
208 OLSR_PRINTF(5, "Friendly name = %s\n", FriendlyName);
210 if (strncmp(FriendlyName, String, MAX_INTERFACE_NAME_LEN) == 0)
214 if (WalkerAddr == NULL) {
215 fprintf(stderr, "No such interface: %s!\n", String);
219 *MiniIndex = WalkerAddr->IfIndex & 255;
225 GetIntInfo(struct InterfaceInfo *Info, char *Name)
228 unsigned char Buff[MAX_INTERFACES * sizeof(MIB_IFROW) + 4];
229 MIB_IFTABLE *IfTable;
230 unsigned long BuffLen;
233 IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
235 struct MibIpInterfaceRow Row;
236 GETIPINTERFACEENTRY InterfaceEntry;
238 if (olsr_cnf->ip_version == AF_INET6) {
239 fprintf(stderr, "IPv6 not supported by GetIntInfo()!\n");
243 if ((Name[0] != 'i' && Name[0] != 'I') || (Name[1] != 'f' && Name[1] != 'F')) {
244 if (FriendlyNameToMiniIndex(&MiniIndex, Name) < 0) {
245 fprintf(stderr, "No such interface: %s!\n", Name);
251 if (IntNameToMiniIndex(&MiniIndex, Name) < 0) {
252 fprintf(stderr, "No such interface: %s!\n", Name);
257 IfTable = (MIB_IFTABLE *) Buff;
259 BuffLen = sizeof(Buff);
261 Res = GetIfTable(IfTable, &BuffLen, FALSE);
263 if (Res != NO_ERROR) {
264 fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
268 for (TabIdx = 0; TabIdx < (int)IfTable->dwNumEntries; TabIdx++) {
269 OLSR_PRINTF(5, "Index = %08x\n", (int)IfTable->table[TabIdx].dwIndex);
271 if ((int)(IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
275 if (TabIdx == (int)IfTable->dwNumEntries) {
276 fprintf(stderr, "No such interface: %s!\n", Name);
280 Info->Index = IfTable->table[TabIdx].dwIndex;
281 Info->Mtu = (int)IfTable->table[TabIdx].dwMtu;
283 Info->Mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
285 Lib = LoadLibrary("iphlpapi.dll");
288 fprintf(stderr, "Cannot load iphlpapi.dll: %08lx\n", GetLastError());
292 InterfaceEntry = (GETIPINTERFACEENTRY) GetProcAddress(Lib, "GetIpInterfaceEntry");
294 if (InterfaceEntry == NULL) {
295 OLSR_PRINTF(5, "Not running on Vista - setting interface metric to 0.\n");
301 memset(&Row, 0, sizeof(struct MibIpInterfaceRow));
303 Row.Family = AF_INET;
304 Row.InterfaceIndex = Info->Index;
306 Res = InterfaceEntry(&Row);
308 if (Res != NO_ERROR) {
309 fprintf(stderr, "GetIpInterfaceEntry() = %08lx", Res);
314 Info->Metric = Row.Metric;
316 OLSR_PRINTF(5, "Running on Vista - interface metric is %d.\n", Info->Metric);
321 BuffLen = sizeof(AdInfo);
323 Res = GetAdaptersInfo(AdInfo, &BuffLen);
325 if (Res != NO_ERROR) {
326 fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(), StrError(Res));
330 for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next) {
331 OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
333 if ((int)(Walker->Index & 255) == MiniIndex)
337 if (Walker == NULL) {
338 fprintf(stderr, "No such interface: %s!\n", Name);
342 inet_pton(AF_INET, Walker->IpAddressList.IpAddress.String, &Info->Addr);
343 inet_pton(AF_INET, Walker->IpAddressList.IpMask.String, &Info->Mask);
345 Info->Broad = Info->Addr | ~Info->Mask;
347 strscpy(Info->Guid, Walker->AdapterName, sizeof(Info->Guid));
349 if ((IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED
350 && IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL) || Info->Addr == 0) {
351 OLSR_PRINTF(3, "Interface %s not up!\n", Name);
358 #if !defined OID_802_11_CONFIGURATION
359 #define OID_802_11_CONFIGURATION 0x0d010211
360 #endif /* !defined OID_802_11_CONFIGURATION */
362 #if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS
363 #define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
364 #endif /* !defined IOCTL_NDIS_QUERY_GLOBAL_STATS */
367 IsWireless(char *IntName)
370 struct InterfaceInfo Info;
375 unsigned char OutBuff[100];
376 unsigned long OutBytes;
378 if (GetIntInfo(&Info, IntName) < 0)
386 strscpy(DevName + 4, Info.Guid, sizeof(DevName) - 4);
388 OLSR_PRINTF(5, "Checking whether interface %s is wireless.\n", DevName);
390 DevHand = CreateFile(DevName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
392 if (DevHand == INVALID_HANDLE_VALUE) {
393 ErrNo = GetLastError();
395 OLSR_PRINTF(5, "CreateFile() = %08x, %s\n", ErrNo, StrError(ErrNo));
399 Oid = OID_802_11_CONFIGURATION;
401 if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS, &Oid, sizeof(Oid), OutBuff, sizeof(OutBuff), &OutBytes, NULL)) {
402 ErrNo = GetLastError();
404 CloseHandle(DevHand);
406 if (ErrNo == ERROR_GEN_FAILURE || ErrNo == ERROR_INVALID_PARAMETER) {
407 OLSR_PRINTF(5, "OID not supported. Device probably not wireless.\n");
411 OLSR_PRINTF(5, "DeviceIoControl() = %08x, %s\n", ErrNo, StrError(ErrNo));
415 CloseHandle(DevHand);
416 #endif /* !defined WINCE */
423 IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
424 unsigned long AdInfoLen;
426 IP_ADDR_STRING *Walker2;
430 if (olsr_cnf->ip_version == AF_INET6) {
431 fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n");
435 AdInfoLen = sizeof(AdInfo);
437 Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
439 if (Res == ERROR_NO_DATA) {
440 printf("No interfaces detected.\n");
444 if (Res != NO_ERROR) {
445 fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
449 for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next) {
450 OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
452 MiniIndexToIntName(IntName, Walker->Index);
454 printf("%s: ", IntName);
456 IsWlan = IsWireless(IntName);
461 else if (IsWlan == 0)
467 for (Walker2 = &Walker->IpAddressList; Walker2 != NULL; Walker2 = Walker2->Next)
468 printf(" %s", Walker2->IpAddress.String);
475 add_hemu_if(struct olsr_if *iface)
477 struct interface_olsr *ifp;
478 union olsr_ip_addr null_addr;
480 struct ipaddr_str buf;
483 if (!iface->host_emul)
486 ifp = olsr_malloc(sizeof(struct interface_olsr), "Interface update 2");
488 memset(ifp, 0, sizeof(struct interface_olsr));
490 /* initialize backpointer */
491 ifp->olsr_if = iface;
493 iface->configured = true;
496 name_size = strlen("hcif01") + 1;
498 ifp->int_name = olsr_malloc(name_size, "Interface update 3");
501 strscpy(ifp->int_name, "hcif01", name_size);
503 OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name);
505 OLSR_PRINTF(1, " Address:%s\n", olsr_ip_to_string(&buf, &iface->hemu_ip));
507 OLSR_PRINTF(1, " NB! This is a emulated interface\n that does not exist in the kernel!\n");
509 ifp->int_next = ifnet;
512 memset(&null_addr, 0, olsr_cnf->ipsize);
513 if (ipequal(&null_addr, &olsr_cnf->main_addr)) {
514 olsr_cnf->main_addr = iface->hemu_ip;
515 olsr_cnf->unicast_src_ip = iface->hemu_ip;
516 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
519 ifp->int_mtu = OLSR_DEFAULT_MTU;
521 ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
526 if (olsr_cnf->ip_version == AF_INET) {
527 struct sockaddr_in sin;
529 memset(&sin, 0, sizeof(sin));
531 sin.sin_family = AF_INET;
532 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
533 sin.sin_port = htons(10150);
536 ifp->ip_addr.v4 = iface->hemu_ip.v4;
538 memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
541 *We create one socket for each interface and bind
542 *the socket to it. This to ensure that we can control
543 *on what interface the message is transmitted
546 ifp->olsr_socket = gethemusocket(&sin);
548 if (ifp->olsr_socket < 0) {
549 olsr_exit("Could not initialize socket", 1);
554 memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
557 /* Send IP as first 4/16 bytes on socket */
558 memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
559 addr[0] = htonl(addr[0]);
560 addr[1] = htonl(addr[1]);
561 addr[2] = htonl(addr[2]);
562 addr[3] = htonl(addr[3]);
564 if (send(ifp->olsr_socket, (char *)addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize) {
565 fprintf(stderr, "Error sending IP!");
568 /* Register socket */
569 add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu, NULL, NULL, SP_PR_READ);
572 * Register functions for periodic message generation
574 ifp->hello_gen_timer =
575 olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
576 olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
578 olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
579 olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
581 olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp,
582 mid_gen_timer_cookie);
584 olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp,
585 hna_gen_timer_cookie);
587 /* Recalculate max topology hold time */
588 if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
589 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
591 ifp->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
592 ifp->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
593 ifp->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
594 ifp->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
595 ifp->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
597 ifp->mode = iface->cnf->mode;
603 chk_if_changed(struct olsr_if *iface)
605 struct ipaddr_str buf;
606 struct interface_olsr *Int;
607 struct InterfaceInfo Info;
610 union olsr_ip_addr OldVal, NewVal;
611 struct sockaddr_in *AddrIn;
613 if (olsr_cnf->ip_version == AF_INET6) {
614 fprintf(stderr, "IPv6 not supported by chk_if_changed()!\n");
618 OLSR_PRINTF(3, "Checking if %s is set down or changed\n", iface->name);
623 if (GetIntInfo(&Info, iface->name) < 0) {
624 olsr_remove_interface(iface);
630 IsWlan = IsWireless(iface->name);
635 if (Int->is_wireless != IsWlan) {
636 OLSR_PRINTF(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan);
638 Int->is_wireless = IsWlan;
640 if (iface->cnf->weight.fixed)
641 Int->int_metric = iface->cnf->weight.value;
644 Int->int_metric = Info.Metric;
649 if (Int->int_mtu != Info.Mtu) {
650 OLSR_PRINTF(1, "\tMTU change: %d -> %d.\n", (int)Int->int_mtu, Info.Mtu);
652 Int->int_mtu = Info.Mtu;
654 net_remove_buffer(Int);
660 OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr;
661 NewVal.v4.s_addr = Info.Addr;
664 OLSR_PRINTF(3, "\tAddress: %s\n", olsr_ip_to_string(&buf, &NewVal));
667 if (NewVal.v4.s_addr != OldVal.v4.s_addr) {
668 OLSR_PRINTF(1, "\tAddress change.\n");
669 OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&buf, &OldVal));
670 OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&buf, &NewVal));
672 Int->ip_addr.v4 = NewVal.v4;
674 AddrIn = (struct sockaddr_in *)&Int->int_addr;
676 AddrIn->sin_family = AF_INET;
677 AddrIn->sin_port = 0;
678 AddrIn->sin_addr = NewVal.v4;
680 if (olsr_cnf->main_addr.v4.s_addr == OldVal.v4.s_addr) {
681 OLSR_PRINTF(1, "\tMain address change.\n");
683 olsr_cnf->main_addr.v4 = NewVal.v4;
690 OLSR_PRINTF(3, "\tNo address change.\n");
692 OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr;
693 NewVal.v4.s_addr = Info.Mask;
696 OLSR_PRINTF(3, "\tNetmask: %s\n", olsr_ip_to_string(&buf, &NewVal));
699 if (NewVal.v4.s_addr != OldVal.v4.s_addr) {
700 OLSR_PRINTF(1, "\tNetmask change.\n");
701 OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&buf, &OldVal));
702 OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&buf, &NewVal));
704 AddrIn = (struct sockaddr_in *)&Int->int_netmask;
706 AddrIn->sin_family = AF_INET;
707 AddrIn->sin_port = 0;
708 AddrIn->sin_addr = NewVal.v4;
714 OLSR_PRINTF(3, "\tNo netmask change.\n");
716 OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr;
717 NewVal.v4.s_addr = Info.Broad;
720 OLSR_PRINTF(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&buf, &NewVal));
723 if (NewVal.v4.s_addr != OldVal.v4.s_addr) {
724 OLSR_PRINTF(1, "\tBroadcast address change.\n");
725 OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&buf, &OldVal));
726 OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&buf, &NewVal));
728 AddrIn = (struct sockaddr_in *)&Int->int_broadaddr;
730 AddrIn->sin_family = AF_INET;
731 AddrIn->sin_port = 0;
732 AddrIn->sin_addr = NewVal.v4;
738 OLSR_PRINTF(3, "\tNo broadcast address change.\n");
741 olsr_trigger_ifchange(Int->if_index, Int, IFCHG_IF_UPDATE);
747 chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
749 struct ipaddr_str buf;
750 struct InterfaceInfo Info;
751 struct interface_olsr *New;
752 union olsr_ip_addr NullAddr;
754 struct sockaddr_in *AddrIn;
757 if (olsr_cnf->ip_version == AF_INET6) {
758 fprintf(stderr, "IPv6 not supported by chk_if_up()!\n");
762 if (GetIntInfo(&Info, iface->name) < 0)
765 New = olsr_malloc(sizeof(struct interface_olsr), "Interface 1");
766 /* initialize backpointer */
767 New->olsr_if = iface;
770 New->immediate_send_tc = (iface->cnf->tc_params.emission_interval < iface->cnf->hello_params.emission_interval);
771 if (olsr_cnf->max_jitter == 0) {
772 /* max_jitter determines the max time to store to-be-send-messages, correlated with random() */
773 olsr_cnf->max_jitter =
774 New->immediate_send_tc ? iface->cnf->tc_params.emission_interval : iface->cnf->hello_params.emission_interval;
777 New->gen_properties = NULL;
779 AddrIn = (struct sockaddr_in *)&New->int_addr;
781 AddrIn->sin_family = AF_INET;
782 AddrIn->sin_port = 0;
783 AddrIn->sin_addr.s_addr = Info.Addr;
785 AddrIn = (struct sockaddr_in *)&New->int_netmask;
787 AddrIn->sin_family = AF_INET;
788 AddrIn->sin_port = 0;
789 AddrIn->sin_addr.s_addr = Info.Mask;
791 AddrIn = (struct sockaddr_in *)&New->int_broadaddr;
793 AddrIn->sin_family = AF_INET;
794 AddrIn->sin_port = 0;
795 AddrIn->sin_addr.s_addr = Info.Broad;
797 if (iface->cnf->ipv4_multicast.v4.s_addr != 0)
798 AddrIn->sin_addr = iface->cnf->ipv4_multicast.v4;
802 New->is_hcif = false;
804 New->int_mtu = Info.Mtu;
806 name_size = strlen(iface->name) + 1;
807 New->int_name = olsr_malloc(name_size, "Interface 2");
808 strscpy(New->int_name, iface->name, name_size);
810 IsWlan = IsWireless(iface->name);
815 New->is_wireless = IsWlan;
817 if (iface->cnf->weight.fixed)
818 New->int_metric = iface->cnf->weight.value;
821 New->int_metric = Info.Metric;
823 New->olsr_seqnum = olsr_random() & 0xffff;
825 New->ttl_index = -32; /* For the first 32 TC's, fish-eye is disabled */
827 OLSR_PRINTF(1, "\tInterface %s set up for use with index %d\n\n", iface->name, New->if_index);
829 OLSR_PRINTF(1, "\tMTU: %d\n", New->int_mtu);
830 OLSR_PRINTF(1, "\tAddress: %s\n", sockaddr4_to_string(&buf, (const struct sockaddr *)&New->int_addr));
831 OLSR_PRINTF(1, "\tNetmask: %s\n", sockaddr4_to_string(&buf, (const struct sockaddr *)&New->int_netmask));
832 OLSR_PRINTF(1, "\tBroadcast address: %s\n", sockaddr4_to_string(&buf, (const struct sockaddr *)&New->int_broadaddr));
834 New->ip_addr.v4 = New->int_addr.sin_addr;
836 New->if_index = Info.Index;
838 OLSR_PRINTF(3, "\tKernel index: %08x\n", New->if_index);
840 New->olsr_socket = getsocket(BUFSPACE, New);
841 New->send_socket = getsocket(0, New);
843 if (New->olsr_socket < 0) {
844 olsr_exit("Could not initialize socket", 1);
847 add_olsr_socket(New->olsr_socket, &olsr_input, NULL, NULL, SP_PR_READ);
849 New->int_next = ifnet;
853 iface->configured = 1;
855 memset(&NullAddr, 0, olsr_cnf->ipsize);
857 if (ipequal(&NullAddr, &olsr_cnf->main_addr)) {
858 olsr_cnf->main_addr = New->ip_addr;
859 olsr_cnf->unicast_src_ip = New->ip_addr;
860 OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
866 * Register functions for periodic message generation
868 New->hello_gen_timer =
869 olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC, HELLO_JITTER, OLSR_TIMER_PERIODIC,
870 olsr_cnf->lq_level == 0 ? &generate_hello : &olsr_output_lq_hello, New, hello_gen_timer_cookie);
872 olsr_start_timer(iface->cnf->tc_params.emission_interval * MSEC_PER_SEC, TC_JITTER, OLSR_TIMER_PERIODIC,
873 olsr_cnf->lq_level == 0 ? &generate_tc : &olsr_output_lq_tc, New, tc_gen_timer_cookie);
875 olsr_start_timer(iface->cnf->mid_params.emission_interval * MSEC_PER_SEC, MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, New,
876 mid_gen_timer_cookie);
878 olsr_start_timer(iface->cnf->hna_params.emission_interval * MSEC_PER_SEC, HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, New,
879 hna_gen_timer_cookie);
881 if (olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
882 olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
884 New->hello_etime = (olsr_reltime) (iface->cnf->hello_params.emission_interval * MSEC_PER_SEC);
885 New->valtimes.hello = reltime_to_me(iface->cnf->hello_params.validity_time * MSEC_PER_SEC);
886 New->valtimes.tc = reltime_to_me(iface->cnf->tc_params.validity_time * MSEC_PER_SEC);
887 New->valtimes.mid = reltime_to_me(iface->cnf->mid_params.validity_time * MSEC_PER_SEC);
888 New->valtimes.hna = reltime_to_me(iface->cnf->hna_params.validity_time * MSEC_PER_SEC);
890 New->mode = iface->cnf->mode;
892 olsr_trigger_ifchange(New->if_index, New, IFCHG_IF_ADD);
898 check_interface_updates(void *dummy __attribute__ ((unused)))
900 struct olsr_if *IntConf;
903 OLSR_PRINTF(3, "Checking for updates in the interface set\n");
906 for (IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next) {
907 if (IntConf->host_emul)
910 if (olsr_cnf->host_emul) /* XXX: TEMPORARY! */
913 if (IntConf->configured)
914 chk_if_changed(IntConf);
917 chk_if_up(IntConf, 3);
926 * indent-tabs-mode: nil