Applied friendly name patch by Sektor.
[olsrd.git] / src / win32 / ifnet.c
index 62e0bad..639ddb6 100644 (file)
@@ -1,49 +1,77 @@
-/* 
- * OLSR ad-hoc routing table management protocol
- * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
+/*
+ * The olsr.org Optimized Link-State Routing daemon (olsrd)
+ * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
+ * All rights reserved.
  *
- * Derived from its Linux counterpart.
- * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
  *
- * This file is part of the olsr.org OLSR daemon.
+ * * Redistributions of source code must retain the above copyright 
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in 
+ *   the documentation and/or other materials provided with the 
+ *   distribution.
+ * * Neither the name of olsr.org, olsrd nor the names of its 
+ *   contributors may be used to endorse or promote products derived 
+ *   from this software without specific prior written permission.
  *
- * olsr.org is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+ * POSSIBILITY OF SUCH DAMAGE.
  *
- * olsr.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Visit http://www.olsr.org for more information.
  *
- * You should have received a copy of the GNU General Public License
- * along with olsr.org; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * $Id: ifnet.c,v 1.6 2004/10/19 21:44:56 tlopatic Exp $
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
  *
+ * $Id: ifnet.c,v 1.31 2006/10/11 20:18:36 tlopatic Exp $
  */
 
-#include "../interfaces.h"
-#include "../olsr.h"
-#include "../net.h"
-#include "../parser.h"
-#include "../socket_parser.h"
-#include "../defs.h"
-#include "../net_os.h"
-#include "../ifnet.h"
-#include "../generate_msg.h"
-#include "../scheduler.h"
-#include "../mantissa.h"
+#include "interfaces.h"
+#include "olsr.h"
+#include "parser.h"
+#include "socket_parser.h"
+#include "defs.h"
+#include "net_os.h"
+#include "ifnet.h"
+#include "generate_msg.h"
+#include "scheduler.h"
+#include "mantissa.h"
+#include "lq_packet.h"
 
 #include <iphlpapi.h>
 #include <iprtrmib.h>
 
+struct InterfaceInfo
+{
+  unsigned int Index;
+  int Mtu;
+  unsigned int Addr;
+  unsigned int Mask;
+  unsigned int Broad;
+  char Guid[39];
+};
+
 void WinSockPError(char *);
 char *StrError(unsigned int ErrNo);
 int inet_pton(int af, char *src, void *dst);
 
+void ListInterfaces(void);
+int GetIntInfo(struct InterfaceInfo *Info, char *Name);
+void RemoveInterface(struct olsr_if *IntConf);
+
 #define MAX_INTERFACES 25
 
 int __stdcall SignalHandler(unsigned long Signal);
@@ -104,98 +132,175 @@ static int IntNameToMiniIndex(int *MiniIndex, char *String)
   return 0;
 }
 
-static int MiniIndexToGuid(char *Guid, int MiniIndex)
+static int FriendlyNameToMiniIndex(int *MiniIndex, char *String)
 {
-  IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
-  unsigned long AdInfoLen;
+  typedef DWORD (*GETADAPTERSADDRESSES)(ULONG Family,
+                                        DWORD Flags,
+                                        PVOID Reserved,
+                                        PIP_ADAPTER_ADDRESSES pAdapterAddresses,
+                                        PULONG pOutBufLen);
+  unsigned long BuffLen;
   unsigned long Res;
+  IP_ADAPTER_ADDRESSES AdAddr[MAX_INTERFACES], *WalkerAddr;
+  char FriendlyName[MAX_INTERFACE_NAME_LEN];
+  HMODULE h;
+  GETADAPTERSADDRESSES pfGetAdaptersAddresses;
   
-  if (olsr_cnf->ip_version == AF_INET6)
+  h = LoadLibrary("iphlpapi.dll");
+
+  if (h == NULL)
   {
-    fprintf(stderr, "IPv6 not supported by MiniIndexToGuid()!\n");
+    fprintf(stderr, "LoadLibrary() = %08lx", GetLastError());
     return -1;
   }
 
-  AdInfoLen = sizeof (AdInfo);
+  pfGetAdaptersAddresses = (GETADAPTERSADDRESSES) GetProcAddress(h, "GetAdaptersAddresses");
 
-  Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
+  if (pfGetAdaptersAddresses == NULL)
+  {
+    fprintf(stderr, "Unable to use adapter friendly name (GetProcAddress() = %08lx)\n", GetLastError());
+    return -1;
+  }
+  
+  BuffLen = sizeof (AdAddr);
+
+  Res = pfGetAdaptersAddresses(AF_INET, 0, NULL, AdAddr, &BuffLen);
 
   if (Res != NO_ERROR)
-  {
-    fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(),
-            StrError(Res));
+  {  
+    fprintf(stderr, "GetAdaptersAddresses() = %08lx", GetLastError());
     return -1;
   }
 
-  for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
+  for (WalkerAddr = AdAddr; WalkerAddr != NULL; WalkerAddr = WalkerAddr->Next)
   {
-    olsr_printf(5, "Index = %08x\n", Walker->Index);
+    OLSR_PRINTF(5, "Index = %08x - ", (int)WalkerAddr->IfIndex);
+
+    wcstombs(FriendlyName, WalkerAddr->FriendlyName, MAX_INTERFACE_NAME_LEN); 
 
-    if ((Walker->Index & 255) == MiniIndex)
+    OLSR_PRINTF(5, "Friendly name = %s\n", FriendlyName);
+
+    if (strncmp(FriendlyName, String, MAX_INTERFACE_NAME_LEN) == 0)
       break;
   }
 
-  if (Walker != NULL)
+  if (WalkerAddr == NULL)
   {
-    olsr_printf(5, "Found interface.\n");
-
-    strcpy(Guid, Walker->AdapterName);
-    return 0;
+    fprintf(stderr, "No such interface: %s!\n", String);
+    return -1;
   }
 
-  olsr_printf(5, "Cannot map mini index %02x to an adapter GUID.\n",
-              MiniIndex);
-  return -1;
+  *MiniIndex = WalkerAddr->IfIndex & 255;
 }
 
-static int AddrToIndex(int *Index, unsigned int Addr)
+int GetIntInfo(struct InterfaceInfo *Info, char *Name)
 {
-  unsigned int IntAddr;
-  IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
-  unsigned long AdInfoLen;
-  IP_ADDR_STRING *Walker2;
+  int MiniIndex;
+  unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4];
+  MIB_IFTABLE *IfTable;
+  unsigned long BuffLen;
   unsigned long Res;
-  
-  olsr_printf(5, "AddrToIndex(%08x)\n", Addr);
+  int TabIdx;
+  IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker;
 
   if (olsr_cnf->ip_version == AF_INET6)
   {
-    fprintf(stderr, "IPv6 not supported by AddrToIndex()!\n");
+    fprintf(stderr, "IPv6 not supported by GetIntInfo()!\n");
     return -1;
   }
 
-  AdInfoLen = sizeof (AdInfo);
+  if ((Name[0] != 'i' && Name[0] != 'I') ||
+      (Name[1] != 'f' && Name[1] != 'F'))
+  {
+    if (FriendlyNameToMiniIndex(&MiniIndex, Name) < 0)
+    {
+      fprintf(stderr, "No such interface: %s!\n", Name);
+      return -1;
+    }
+  }
 
-  Res = GetAdaptersInfo(AdInfo, &AdInfoLen);
+  else
+  {
+    if (IntNameToMiniIndex(&MiniIndex, Name) < 0)
+    {
+      fprintf(stderr, "No such interface: %s!\n", Name);
+      return -1;
+    }
+  }
+
+  IfTable = (MIB_IFTABLE *)Buff;
+
+  BuffLen = sizeof (Buff);
+
+  Res = GetIfTable(IfTable, &BuffLen, FALSE);
 
   if (Res != NO_ERROR)
   {
-    fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res));
+    fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
+    return -1;
+  }
+
+  for (TabIdx = 0; TabIdx < (int)IfTable->dwNumEntries; TabIdx++)
+  {
+    OLSR_PRINTF(5, "Index = %08x\n", (int)IfTable->table[TabIdx].dwIndex);
+
+    if ((int)(IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
+      break;
+  }
+
+  if (TabIdx == (int)IfTable->dwNumEntries)
+  {
+    fprintf(stderr, "No such interface: %s!\n", Name);
+    return -1;
+  }
+    
+  Info->Index = IfTable->table[TabIdx].dwIndex;
+  Info->Mtu = (int)IfTable->table[TabIdx].dwMtu;
+
+  Info->Mtu -= (olsr_cnf->ip_version == AF_INET6) ?
+    UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
+
+  BuffLen = sizeof (AdInfo);
+
+  Res = GetAdaptersInfo(AdInfo, &BuffLen);
+
+  if (Res != NO_ERROR)
+  {
+    fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(),
+            StrError(Res));
     return -1;
   }
 
   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
   {
-    olsr_printf(5, "Index = %08x\n", Walker->Index);
+    OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index);
 
-    for (Walker2 = &Walker->IpAddressList; Walker2 != NULL;
-         Walker2 = Walker2->Next)
-    {
-      inet_pton(AF_INET, Walker2->IpAddress.String, &IntAddr);
+    if ((int)(Walker->Index & 255) == MiniIndex)
+      break;
+  }
 
-      olsr_printf(5, "\tIP address = %08x\n", IntAddr);
+  if (Walker == NULL)
+  {
+    fprintf(stderr, "No such interface: %s!\n", Name);
+    return -1;
+  }
 
-      if (Addr == IntAddr)
-      {
-        olsr_printf(5, "Found interface.\n");
-        *Index = Walker->Index;
-        return 0;
-      }
-    }
+  inet_pton(AF_INET, Walker->IpAddressList.IpAddress.String, &Info->Addr);
+  inet_pton(AF_INET, Walker->IpAddressList.IpMask.String, &Info->Mask);
+
+  Info->Broad = Info->Addr | ~Info->Mask;
+
+  strcpy(Info->Guid, Walker->AdapterName);
+
+  if ((IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED &&
+      IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL) ||
+      Info->Addr == 0)
+  {
+    OLSR_PRINTF(3, "Interface %s not up!\n", Name);
+    return -1;
   }
 
-  olsr_printf(5, "Cannot map IP address %08x to an adapter index.\n", Addr);
-  return -1;
+  return 0;
 }
 
 #if !defined OID_802_11_CONFIGURATION
@@ -208,7 +313,8 @@ static int AddrToIndex(int *Index, unsigned int Addr)
 
 static int IsWireless(char *IntName)
 {
-  int MiniIndex;
+#if !defined WINCE
+  struct InterfaceInfo Info;
   char DevName[43];
   HANDLE DevHand;
   unsigned int ErrNo;
@@ -216,7 +322,7 @@ static int IsWireless(char *IntName)
   unsigned char OutBuff[100];
   unsigned long OutBytes;
 
-  if (IntNameToMiniIndex(&MiniIndex, IntName) < 0)
+  if (GetIntInfo(&Info, IntName) < 0)
     return -1;
 
   DevName[0] = '\\';
@@ -224,10 +330,9 @@ static int IsWireless(char *IntName)
   DevName[2] = '.';
   DevName[3] = '\\';
 
-  if (MiniIndexToGuid(DevName + 4, MiniIndex) < 0)
-    return -1;
+  strcpy(DevName + 4, Info.Guid);
 
-  olsr_printf(5, "Checking whether interface %s is wireless.\n", DevName);
+  OLSR_PRINTF(5, "Checking whether interface %s is wireless.\n", DevName);
 
   DevHand = CreateFile(DevName, GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
@@ -237,7 +342,7 @@ static int IsWireless(char *IntName)
   {
     ErrNo = GetLastError();
 
-    olsr_printf(5, "CreateFile() = %08lx, %s\n", ErrNo, StrError(ErrNo));
+    OLSR_PRINTF(5, "CreateFile() = %08x, %s\n", ErrNo, StrError(ErrNo));
     return -1;
   }
 
@@ -254,15 +359,16 @@ static int IsWireless(char *IntName)
 
     if (ErrNo == ERROR_GEN_FAILURE)
     {
-      olsr_printf(5, "OID not supported. Device probably not wireless.\n");
+      OLSR_PRINTF(5, "OID not supported. Device probably not wireless.\n")
       return 0;
     }
 
-    olsr_printf(5, "DeviceIoControl() = %08lx, %s\n", ErrNo, StrError(ErrNo));
+    OLSR_PRINTF(5, "DeviceIoControl() = %08x, %s\n", ErrNo, StrError(ErrNo))
     return -1;
   }
 
   CloseHandle(DevHand);
+#endif
   return 1;
 }
 
@@ -299,7 +405,7 @@ void ListInterfaces(void)
 
   for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next)
   {
-    olsr_printf(5, "Index = %08x\n", Walker->Index);
+    OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index)
 
     MiniIndexToIntName(IntName, Walker->Index);
 
@@ -324,240 +430,279 @@ void ListInterfaces(void)
   }
 }
 
-int InterfaceEntry(MIB_IFROW *IntPara, int *Index, struct olsr_if *IntConf)
+void RemoveInterface(struct olsr_if *IntConf)
 {
-  int MiniIndex;
-  unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4];
-  MIB_IFTABLE *IfTable;
-  unsigned long BuffLen;
-  unsigned long Res;
-  int TabIdx;
-
-  if (olsr_cnf->ip_version == AF_INET6)
-  {
-    fprintf(stderr, "IPv6 not supported by AdapterInfo()!\n");
-    return -1;
-  }
-
-  if (IntNameToMiniIndex(&MiniIndex, IntConf->name) < 0)
-  {
-    fprintf(stderr, "No such interface: %s!\n", IntConf->name);
-    return -1;
-  }
+  struct interface *Int, *Prev;
 
-  IfTable = (MIB_IFTABLE *)Buff;
+  OLSR_PRINTF(1, "Removing interface %s.\n", IntConf->name)
+  
+  Int = IntConf->interf;
 
-  BuffLen = sizeof (Buff);
+  run_ifchg_cbs(Int, IFCHG_IF_ADD);
 
-  Res = GetIfTable(IfTable, &BuffLen, FALSE);
+  if (Int == ifnet)
+    ifnet = Int->int_next;
 
-  if (Res != NO_ERROR)
+  else
   {
-    fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res));
-    return -1;
+    for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
+
+    Prev->int_next = Int->int_next;
   }
 
-  for (TabIdx = 0; TabIdx < IfTable->dwNumEntries; TabIdx++)
+  if(COMP_IP(&olsr_cnf->main_addr, &Int->ip_addr))
   {
-    olsr_printf(5, "Index = %08x\n", IfTable->table[TabIdx].dwIndex);
+    if(ifnet == NULL)
+    {
+      memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize);
+      OLSR_PRINTF(1, "Removed last interface. Cleared main address.\n")
+    }
 
-    if ((IfTable->table[TabIdx].dwIndex & 255) == MiniIndex)
-      break;
+    else
+    {
+      COPY_IP(&olsr_cnf->main_addr, &ifnet->ip_addr);
+      OLSR_PRINTF(1, "New main address: %s.\n", olsr_ip_to_string(&olsr_cnf->main_addr))
+    }
   }
 
-  if (TabIdx == IfTable->dwNumEntries)
-  {
-    fprintf(stderr, "No such interface: %s!\n", IntConf->name);
-    return -1;
-  }
-    
-  *Index = IfTable->table[TabIdx].dwIndex;
+  if (olsr_cnf->lq_level == 0)
+    {
+      olsr_remove_scheduler_event(&generate_hello, Int,
+                                  IntConf->cnf->hello_params.emission_interval,
+                                  0, NULL);
 
-  memcpy(IntPara, &IfTable->table[TabIdx], sizeof (MIB_IFROW));
-  return 0;
-}
+      olsr_remove_scheduler_event(&generate_tc, Int,
+                                  IntConf->cnf->tc_params.emission_interval,
+                                  0, NULL);
+    }
 
-int InterfaceInfo(INTERFACE_INFO *IntPara, int *Index, struct olsr_if *IntConf)
-{
-  int MiniIndex;
-  int Sock;
-  INTERFACE_INFO IntInfo[25];
-  long Num;
-  int WsIdx;
-  int CandIndex;
+  else
+    {
+      olsr_remove_scheduler_event(&olsr_output_lq_hello, Int,
+                                  IntConf->cnf->hello_params.emission_interval,
+                                  0, NULL);
 
-  if (IntNameToMiniIndex(&MiniIndex, IntConf->name) < 0)
-  {
-    fprintf(stderr, "No such interface: %s!\n", IntConf->name);
-    return -1;
-  }
+      olsr_remove_scheduler_event(&olsr_output_lq_tc, Int,
+                                  IntConf->cnf->tc_params.emission_interval,
+                                  0, NULL);
+    }
 
-  Sock = socket(olsr_cnf->ip_version, SOCK_STREAM, IPPROTO_TCP);
+  olsr_remove_scheduler_event(&generate_mid, Int,
+                              IntConf->cnf->mid_params.emission_interval,
+                              0, NULL);
 
-  if (Sock < 0)
-  {
-    WinSockPError("socket()");
-    return -1;
-  }
+  olsr_remove_scheduler_event(&generate_hna, Int,
+                              IntConf->cnf->hna_params.emission_interval,
+                              0, NULL);
 
-  if (WSAIoctl(Sock, SIO_GET_INTERFACE_LIST, NULL, 0,
-               IntInfo, sizeof (IntInfo), &Num, NULL, NULL) < 0)
-  {
-    WinSockPError("WSAIoctl(SIO_GET_INTERFACE_LIST)");
-    closesocket(Sock);
-    return -1;
-  }
+  net_remove_buffer(Int);
 
-  closesocket(Sock);
+  IntConf->configured = 0;
+  IntConf->interf = NULL;
 
-  Num /= sizeof (INTERFACE_INFO);
+  closesocket(Int->olsr_socket);
+  remove_olsr_socket(Int->olsr_socket, &olsr_input);
 
-  olsr_printf(5, "%s:\n", IntConf->name);
+  free(Int->int_name);
+  free(Int);
 
-  for (WsIdx = 0; WsIdx < Num; WsIdx++)
+  if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
   {
-    if (AddrToIndex(&CandIndex,
-                    IntInfo[WsIdx].iiAddress.AddressIn.sin_addr.s_addr) < 0)
-      continue;
-
-    if ((CandIndex & 255) == MiniIndex)
-      break;
+    OLSR_PRINTF(1, "No more active interfaces - exiting.\n")
+    olsr_cnf->exit_value = EXIT_FAILURE;
+    CallSignalHandler();
   }
+}
 
-  if (WsIdx == Num)
-  {
-    fprintf(stderr, "No such interface: %s!\n", IntConf->name);
+int add_hemu_if(struct olsr_if *iface)
+{
+  struct interface *ifp;
+  union olsr_ip_addr null_addr;
+  olsr_u32_t addr[4];
+
+  if(!iface->host_emul)
     return -1;
-  }
-    
-  *Index = CandIndex;
 
-  olsr_printf(5, "\tIndex: %08x\n", *Index);
+  ifp = olsr_malloc(sizeof (struct interface), "Interface update 2");
 
-  olsr_printf(5, "\tFlags: %08x\n", IntInfo[WsIdx].iiFlags);
+  memset(ifp, 0, sizeof (struct interface));
 
-  if ((IntInfo[WsIdx].iiFlags & IFF_UP) == 0)
-  {
-    olsr_printf(1, "\tInterface not up - skipping it...\n");
-    return -1;
-  }
+  iface->configured = OLSR_TRUE;
+  iface->interf = ifp;
 
-  if (olsr_cnf->ip_version == AF_INET &&
-      (IntInfo[WsIdx].iiFlags & IFF_BROADCAST) == 0)
-  {
-    olsr_printf(1, "\tNo broadcast - skipping it...\n");
-    return -1;
-  }
+  ifp->is_hcif = OLSR_TRUE;
+  ifp->int_name = olsr_malloc(strlen("hcif01") + 1, "Interface update 3");
+  ifp->int_metric = 0;
 
-  if ((IntInfo[WsIdx].iiFlags & IFF_LOOPBACK) != 0)
-  {
-    olsr_printf(1, "\tThis is a loopback interface - skipping it...\n");
-    return -1;
-  }
+  strcpy(ifp->int_name, "hcif01");
 
-  // Windows seems to always return 255.255.255.255 as broadcast
-  // address, so I've tried using (address | ~netmask).
+  OLSR_PRINTF(1, "Adding %s(host emulation):\n", ifp->int_name)
 
-  {
-    struct sockaddr_in *sin_a, *sin_n, *sin_b;
-    unsigned int a, n, b;
+  OLSR_PRINTF(1, "       Address:%s\n", olsr_ip_to_string(&iface->hemu_ip));
 
-    sin_a = (struct sockaddr_in *)&IntInfo[WsIdx].iiAddress;
-    sin_n = (struct sockaddr_in *)&IntInfo[WsIdx].iiNetmask;
-    sin_b = (struct sockaddr_in *)&IntInfo[WsIdx].iiBroadcastAddress;
+  OLSR_PRINTF(1, "       Index:%d\n", iface->index);
 
-    a = sin_a->sin_addr.s_addr;
-    n = sin_n->sin_addr.s_addr;
-    b = sin_b->sin_addr.s_addr =
-      sin_a->sin_addr.s_addr | ~sin_n->sin_addr.s_addr;
-  }
+  OLSR_PRINTF(1, "       NB! This is a emulated interface\n       that does not exist in the kernel!\n");
 
-  memcpy(IntPara, &IntInfo[WsIdx], sizeof (INTERFACE_INFO));
-  return 0;
-}
+  ifp->int_next = ifnet;
+  ifnet = ifp;
 
-void RemoveInterface(struct olsr_if *IntConf)
-{
-  struct interface *Int, *Prev;
-  struct ifchgf *Walker;
+  memset(&null_addr, 0, olsr_cnf->ipsize);
+  if(COMP_IP(&null_addr, &olsr_cnf->main_addr))
+    {
+      COPY_IP(&olsr_cnf->main_addr, &iface->hemu_ip);
+      OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
+    }
 
-  olsr_printf(1, "Removing interface %s.\n", IntConf->name);
-  
-  Int = IntConf->interf;
+  /* setting the interfaces number*/
+  ifp->if_nr = iface->index;
 
-  for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
-    Walker->function(Int, IFCHG_IF_REMOVE);
+  ifp->int_mtu = OLSR_DEFAULT_MTU;
 
-  if (Int == ifnet)
-    ifnet = Int->int_next;
+  ifp->int_mtu -= (olsr_cnf->ip_version == AF_INET6) ?
+    UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE;
 
-  else
-  {
-    for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next);
+  /* Set up buffer */
+  net_add_buffer(ifp);
 
-    Prev->int_next = Int->int_next;
-  }
 
-  if(COMP_IP(&main_addr, &Int->ip_addr))
-  {
-    if(ifnet == NULL)
+  if(olsr_cnf->ip_version == AF_INET)
     {
-      memset(&main_addr, 0, ipsize);
-      olsr_printf(1, "Removed last interface. Cleared main address.\n");
-    }
+      struct sockaddr_in sin;
 
-    else
-    {
-      COPY_IP(&main_addr, &ifnet->ip_addr);
-      olsr_printf(1, "New main address: %s.\n", olsr_ip_to_string(&main_addr));
-    }
-  }
+      memset(&sin, 0, sizeof(sin));
 
-  olsr_remove_scheduler_event(&generate_hello, Int,
-                              IntConf->cnf->hello_params.emission_interval,
-                              0, NULL);
+      sin.sin_family = AF_INET;
+      sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+      sin.sin_port = htons(10150);
+     /* IP version 4 */
+      ifp->ip_addr.v4 = iface->hemu_ip.v4;
 
-  olsr_remove_scheduler_event(&generate_tc, Int,
-                              IntConf->cnf->tc_params.emission_interval,
-                              0, NULL);
+      memcpy(&((struct sockaddr_in *)&ifp->int_addr)->sin_addr, &iface->hemu_ip, olsr_cnf->ipsize);
+      
+      /*
+       *We create one socket for each interface and bind
+       *the socket to it. This to ensure that we can control
+       *on what interface the message is transmitted
+       */
+      
+      ifp->olsr_socket = gethemusocket(&sin);
+      
+      if (ifp->olsr_socket < 0)
+       {
+         fprintf(stderr, "Could not initialize socket... exiting!\n\n");
+         exit(1);
+       }
 
-  olsr_remove_scheduler_event(&generate_mid, Int,
-                              IntConf->cnf->mid_params.emission_interval,
-                              0, NULL);
+    }
+  else
+    {
+      /* IP version 6 */
+      memcpy(&ifp->ip_addr, &iface->hemu_ip, olsr_cnf->ipsize);
+
+#if 0      
+      /*
+       *We create one socket for each interface and bind
+       *the socket to it. This to ensure that we can control
+       *on what interface the message is transmitted
+       */
+      
+      ifp->olsr_socket = gethcsocket6(&addrsock6, bufspace, ifp->int_name);
+      
+      join_mcast(ifp, ifp->olsr_socket);
+      
+      if (ifp->olsr_socket < 0)
+       {
+         fprintf(stderr, "Could not initialize socket... exiting!\n\n");
+         exit(1);
+       }
+      
+#endif
+    }
 
-  olsr_remove_scheduler_event(&generate_hna, Int,
-                              IntConf->cnf->hna_params.emission_interval,
-                              0, NULL);
+  /* Send IP as first 4/16 bytes on socket */
+  memcpy(addr, iface->hemu_ip.v6.s6_addr, olsr_cnf->ipsize);
+  addr[0] = htonl(addr[0]);
+  addr[1] = htonl(addr[1]);
+  addr[2] = htonl(addr[2]);
+  addr[3] = htonl(addr[3]);
 
-  net_remove_buffer(Int);
+  if(send(ifp->olsr_socket, (char *)addr, olsr_cnf->ipsize, 0) != (int)olsr_cnf->ipsize)
+    {
+      fprintf(stderr, "Error sending IP!");
+    }  
+  
+  /* Register socket */
+  add_olsr_socket(ifp->olsr_socket, &olsr_input_hostemu);
 
-  IntConf->configured = 0;
-  IntConf->interf = NULL;
 
-  closesocket(Int->olsr_socket);
-  remove_olsr_socket(Int->olsr_socket, &olsr_input);
+  if (olsr_cnf->lq_level == 0)
+    {
+      olsr_register_scheduler_event(&generate_hello, 
+                                    ifp, 
+                                    iface->cnf->hello_params.emission_interval, 
+                                    0, 
+                                    NULL);
+      olsr_register_scheduler_event(&generate_tc, 
+                                    ifp, 
+                                    iface->cnf->tc_params.emission_interval,
+                                    0, 
+                                    NULL);
+    }
 
-  free(Int->int_name);
-  free(Int);
+  else
+    {
+      olsr_register_scheduler_event(&olsr_output_lq_hello, 
+                                    ifp, 
+                                    iface->cnf->hello_params.emission_interval, 
+                                    0, 
+                                    NULL);
+      olsr_register_scheduler_event(&olsr_output_lq_tc, 
+                                    ifp, 
+                                    iface->cnf->tc_params.emission_interval,
+                                    0, 
+                                    NULL);
+    }
 
-  if (ifnet == NULL && !olsr_cnf->allow_no_interfaces)
-  {
-    olsr_printf(1, "No more active interfaces - exiting.\n");
-    exit_value = EXIT_FAILURE;
-    CallSignalHandler();
-  }
+  olsr_register_scheduler_event(&generate_mid, 
+                               ifp, 
+                               iface->cnf->mid_params.emission_interval,
+                               0, 
+                               NULL);
+  olsr_register_scheduler_event(&generate_hna, 
+                               ifp, 
+                               iface->cnf->hna_params.emission_interval,
+                               0, 
+                               NULL);
+
+  /* Recalculate max jitter */
+
+  if((olsr_cnf->max_jitter == 0) || 
+     ((iface->cnf->hello_params.emission_interval / 4) < olsr_cnf->max_jitter))
+    olsr_cnf->max_jitter = iface->cnf->hello_params.emission_interval / 4;
+
+  /* Recalculate max topology hold time */
+  if(olsr_cnf->max_tc_vtime < iface->cnf->tc_params.emission_interval)
+    olsr_cnf->max_tc_vtime = iface->cnf->tc_params.emission_interval;
+
+  ifp->hello_etime = iface->cnf->hello_params.emission_interval;
+  ifp->valtimes.hello = double_to_me(iface->cnf->hello_params.validity_time);
+  ifp->valtimes.tc = double_to_me(iface->cnf->tc_params.validity_time);
+  ifp->valtimes.mid = double_to_me(iface->cnf->mid_params.validity_time);
+  ifp->valtimes.hna = double_to_me(iface->cnf->hna_params.validity_time);
+
+  return 1;
 }
 
 int chk_if_changed(struct olsr_if *IntConf)
 {
   struct interface *Int;
-  INTERFACE_INFO IntInfo;
-  MIB_IFROW IntRow;
-  int Index;
+  struct InterfaceInfo Info;
   int Res;
-  union olsr_ip_addr OldVal, NewVal;
-  struct ifchgf *Walker;
   int IsWlan;
+  union olsr_ip_addr OldVal, NewVal;
+  struct sockaddr_in *AddrIn;
 
   if (olsr_cnf->ip_version == AF_INET6)
   {
@@ -566,13 +711,12 @@ int chk_if_changed(struct olsr_if *IntConf)
   }
 
 #ifdef DEBUG
-  olsr_printf(3, "Checking if %s is set down or changed\n", IntConf->name);
+  OLSR_PRINTF(3, "Checking if %s is set down or changed\n", IntConf->name)
 #endif
 
   Int = IntConf->interf;
 
-  if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
-      InterfaceEntry(&IntRow, &Index, IntConf))
+  if (GetIntInfo(&Info, IntConf->name) < 0)
   {
     RemoveInterface(IntConf);
     return 1;
@@ -587,19 +731,25 @@ int chk_if_changed(struct olsr_if *IntConf)
 
   if (Int->is_wireless != IsWlan)
   {
-    olsr_printf(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan);
+    OLSR_PRINTF(1, "\tLAN/WLAN change: %d -> %d.\n", Int->is_wireless, IsWlan)
 
     Int->is_wireless = IsWlan;
-    Int->int_metric = IsWlan;
+
+    if (IntConf->cnf->weight.fixed)
+      Int->int_metric = IntConf->cnf->weight.value;
+
+    else
+      Int->int_metric = IsWlan;
 
     Res = 1;
   }
 
-  if (Int->int_mtu != IntRow.dwMtu)
+  if (Int->int_mtu != Info.Mtu)
   {
-    olsr_printf(1, "\tMTU change: %d -> %d.\n", Int->int_mtu, IntRow.dwMtu);
+    OLSR_PRINTF(1, "\tMTU change: %d -> %d.\n", (int)Int->int_mtu,
+                Info.Mtu);
 
-    Int->int_mtu = IntRow.dwMtu;
+    Int->int_mtu = Info.Mtu;
 
     net_remove_buffer(Int);
     net_add_buffer(Int);
@@ -608,96 +758,103 @@ int chk_if_changed(struct olsr_if *IntConf)
   }
 
   OldVal.v4 = ((struct sockaddr_in *)&Int->int_addr)->sin_addr.s_addr;
-  NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiAddress)->sin_addr.s_addr;
+  NewVal.v4 = Info.Addr;
 
 #ifdef DEBUG
-  olsr_printf(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal));
+  OLSR_PRINTF(3, "\tAddress: %s\n", olsr_ip_to_string(&NewVal))
 #endif
 
   if (NewVal.v4 != OldVal.v4)
   {
-    olsr_printf(1, "\tAddress change.\n");
-    olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
-    olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
+    OLSR_PRINTF(1, "\tAddress change.\n")
+    OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
+    OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
 
     Int->ip_addr.v4 = NewVal.v4;
 
-    memcpy(&Int->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
+    AddrIn = (struct sockaddr_in *)&Int->int_addr;
+
+    AddrIn->sin_family = AF_INET;
+    AddrIn->sin_port = 0;
+    AddrIn->sin_addr.s_addr = NewVal.v4;
 
-    if (main_addr.v4 == OldVal.v4)
+    if (olsr_cnf->main_addr.v4 == OldVal.v4)
     {
-      olsr_printf(1, "\tMain address change.\n");
+      OLSR_PRINTF(1, "\tMain address change.\n")
 
-      main_addr.v4 = NewVal.v4;
+      olsr_cnf->main_addr.v4 = NewVal.v4;
     }
 
     Res = 1;
   }
 
   else
-    olsr_printf(3, "\tNo address change.\n");
+    OLSR_PRINTF(3, "\tNo address change.\n")
 
   OldVal.v4 = ((struct sockaddr_in *)&Int->int_netmask)->sin_addr.s_addr;
-  NewVal.v4 = ((struct sockaddr_in *)&IntInfo.iiNetmask)->sin_addr.s_addr;
+  NewVal.v4 = Info.Mask;
 
 #ifdef DEBUG
-  olsr_printf(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal));
+  OLSR_PRINTF(3, "\tNetmask: %s\n", olsr_ip_to_string(&NewVal))
 #endif
 
-  if(NewVal.v4 != OldVal.v4)
+  if (NewVal.v4 != OldVal.v4)
   {
-    olsr_printf(1, "\tNetmask change.\n");
-    olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
-    olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
+    OLSR_PRINTF(1, "\tNetmask change.\n")
+    OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
+    OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
+
+    AddrIn = (struct sockaddr_in *)&Int->int_netmask;
 
-    memcpy(&Int->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
+    AddrIn->sin_family = AF_INET;
+    AddrIn->sin_port = 0;
+    AddrIn->sin_addr.s_addr = NewVal.v4;
 
     Res = 1;
   }
 
   else
-    olsr_printf(3, "\tNo netmask change.\n");
+    OLSR_PRINTF(3, "\tNo netmask change.\n")
 
   OldVal.v4 = ((struct sockaddr_in *)&Int->int_broadaddr)->sin_addr.s_addr;
-  NewVal.v4 =
-    ((struct sockaddr_in *)&IntInfo.iiBroadcastAddress)->sin_addr.s_addr;
+  NewVal.v4 = Info.Broad;
 
 #ifdef DEBUG
-  olsr_printf(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal));
+  OLSR_PRINTF(3, "\tBroadcast address: %s\n", olsr_ip_to_string(&NewVal))
 #endif
 
-  if(NewVal.v4 != OldVal.v4)
+  if (NewVal.v4 != OldVal.v4)
   {
-    olsr_printf(1, "\tBroadcast address change.\n");
-    olsr_printf(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal));
-    olsr_printf(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal));
+    OLSR_PRINTF(1, "\tBroadcast address change.\n")
+    OLSR_PRINTF(1, "\tOld: %s\n", olsr_ip_to_string(&OldVal))
+    OLSR_PRINTF(1, "\tNew: %s\n", olsr_ip_to_string(&NewVal))
 
-    memcpy(&Int->int_broadaddr, &IntInfo.iiBroadcastAddress,
-           sizeof (struct sockaddr_in));
+    AddrIn = (struct sockaddr_in *)&Int->int_broadaddr;
+
+    AddrIn->sin_family = AF_INET;
+    AddrIn->sin_port = 0;
+    AddrIn->sin_addr.s_addr = NewVal.v4;
 
     Res = 1;
   }
 
   else
-    olsr_printf(3, "\tNo broadcast address change.\n");
+    OLSR_PRINTF(3, "\tNo broadcast address change.\n")
 
   if (Res != 0)
-    for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
-      Walker->function(Int, IFCHG_IF_UPDATE);
+    run_ifchg_cbs(Int, IFCHG_IF_UPDATE);
 
   return Res;
 }
 
 int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
 {
+  struct InterfaceInfo Info;
   struct interface *New;
   union olsr_ip_addr NullAddr;
-  INTERFACE_INFO IntInfo;
-  MIB_IFROW IntRow;
-  int Index;
   unsigned int AddrSockAddr;
-  struct ifchgf *Walker;
   int IsWlan;
+  struct sockaddr_in *AddrIn;
   
   if (olsr_cnf->ip_version == AF_INET6)
   {
@@ -705,26 +862,38 @@ int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
     return 0;
   }
 
-  if (InterfaceInfo(&IntInfo, &Index, IntConf) < 0 ||
-      InterfaceEntry(&IntRow, &Index, IntConf) < 0)
+  if (GetIntInfo(&Info, IntConf->name) < 0)
     return 0;
 
   New = olsr_malloc(sizeof (struct interface), "Interface 1");
-      
-  memcpy(&New->int_addr, &IntInfo.iiAddress, sizeof (struct sockaddr_in));
+  New->gen_properties = NULL;
+
+  AddrIn = (struct sockaddr_in *)&New->int_addr;
+
+  AddrIn->sin_family = AF_INET;
+  AddrIn->sin_port = 0;
+  AddrIn->sin_addr.s_addr = Info.Addr;
+
+  AddrIn = (struct sockaddr_in *)&New->int_netmask;
+
+  AddrIn->sin_family = AF_INET;
+  AddrIn->sin_port = 0;
+  AddrIn->sin_addr.s_addr = Info.Mask;
 
-  memcpy(&New->int_netmask, &IntInfo.iiNetmask, sizeof (struct sockaddr_in));
+  AddrIn = (struct sockaddr_in *)&New->int_broadaddr;
 
-  memcpy(&New->int_broadaddr, &IntInfo.iiBroadcastAddress,
-         sizeof (struct sockaddr_in));
+  AddrIn->sin_family = AF_INET;
+  AddrIn->sin_port = 0;
+  AddrIn->sin_addr.s_addr = Info.Broad;
 
   if (IntConf->cnf->ipv4_broadcast.v4 != 0)
-    ((struct sockaddr_in *)&New->int_broadaddr)->sin_addr.s_addr =
-      IntConf->cnf->ipv4_broadcast.v4;
+    AddrIn->sin_addr.s_addr = IntConf->cnf->ipv4_broadcast.v4;
 
-  New->int_flags = IntInfo.iiFlags;
+  New->int_flags = 0;
 
-  New->int_mtu = IntRow.dwMtu;
+  New->is_hcif = OLSR_FALSE;
+
+  New->int_mtu = Info.Mtu;
 
   New->int_name = olsr_malloc(strlen (IntConf->name) + 1, "Interface 2");
   strcpy(New->int_name, IntConf->name);
@@ -737,25 +906,30 @@ int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
     IsWlan = 1;
 
   New->is_wireless = IsWlan;
-  New->int_metric = IsWlan;
+
+  if (IntConf->cnf->weight.fixed)
+    New->int_metric = IntConf->cnf->weight.value;
+
+  else
+    New->int_metric = IsWlan;
 
   New->olsr_seqnum = random() & 0xffff;
     
-  olsr_printf(1, "\tInterface %s set up for use with index %d\n\n",
-              IntConf->name, New->if_nr);
+  OLSR_PRINTF(1, "\tInterface %s set up for use with index %d\n\n",
+              IntConf->name, New->if_nr)
       
-  olsr_printf(1, "\tMTU: %d\n", New->int_mtu);
-  olsr_printf(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr));
-  olsr_printf(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask));
-  olsr_printf(1, "\tBroadcast address: %s\n",
-              sockaddr_to_string(&New->int_broadaddr));
+  OLSR_PRINTF(1, "\tMTU: %d\n", New->int_mtu)
+  OLSR_PRINTF(1, "\tAddress: %s\n", sockaddr_to_string(&New->int_addr))
+  OLSR_PRINTF(1, "\tNetmask: %s\n", sockaddr_to_string(&New->int_netmask))
+  OLSR_PRINTF(1, "\tBroadcast address: %s\n",
+              sockaddr_to_string(&New->int_broadaddr))
 
   New->ip_addr.v4 =
     ((struct sockaddr_in *)&New->int_addr)->sin_addr.s_addr;
       
-  New->if_index = Index;
+  New->if_index = Info.Index;
 
-  olsr_printf(3, "\tKernel index: %08x\n", New->if_index);
+  OLSR_PRINTF(3, "\tKernel index: %08x\n", New->if_index)
 
   AddrSockAddr = addrsock.sin_addr.s_addr;
   addrsock.sin_addr.s_addr = New->ip_addr.v4;
@@ -779,24 +953,37 @@ int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
   IntConf->interf = New;
   IntConf->configured = 1;
 
-  memset(&NullAddr, 0, ipsize);
+  memset(&NullAddr, 0, olsr_cnf->ipsize);
   
-  if(COMP_IP(&NullAddr, &main_addr))
+  if(COMP_IP(&NullAddr, &olsr_cnf->main_addr))
   {
-    COPY_IP(&main_addr, &New->ip_addr);
-
-    olsr_printf(1, "New main address: %s\n", olsr_ip_to_string(&main_addr));
+    COPY_IP(&olsr_cnf->main_addr, &New->ip_addr);
+    OLSR_PRINTF(1, "New main address: %s\n", olsr_ip_to_string(&olsr_cnf->main_addr))
   }
 
   net_add_buffer(New);
 
-  olsr_register_scheduler_event(&generate_hello, New,
-                                IntConf->cnf->hello_params.emission_interval,
-                                0, NULL);
+  if (olsr_cnf->lq_level == 0)
+  {
+    olsr_register_scheduler_event(&generate_hello, New,
+                                  IntConf->cnf->hello_params.emission_interval,
+                                  0, NULL);
 
-  olsr_register_scheduler_event(&generate_tc, New,
-                                IntConf->cnf->tc_params.emission_interval,
-                                0, NULL);
+    olsr_register_scheduler_event(&generate_tc, New,
+                                  IntConf->cnf->tc_params.emission_interval,
+                                  0, NULL);
+  }
+
+  else
+  {
+    olsr_register_scheduler_event(&olsr_output_lq_hello, New,
+                                  IntConf->cnf->hello_params.emission_interval,
+                                  0, NULL);
+
+    olsr_register_scheduler_event(&olsr_output_lq_tc, New,
+                                  IntConf->cnf->tc_params.emission_interval,
+                                  0, NULL);
+  }
 
   olsr_register_scheduler_event(&generate_mid, New,
                                 IntConf->cnf->mid_params.emission_interval,
@@ -806,23 +993,21 @@ int chk_if_up(struct olsr_if *IntConf, int DebugLevel)
                                 IntConf->cnf->hna_params.emission_interval,
                                 0, NULL);
 
-  if(max_jitter == 0 ||
-     IntConf->cnf->hello_params.emission_interval / 4 < max_jitter)
-    max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
+  if(olsr_cnf->max_jitter == 0 ||
+     IntConf->cnf->hello_params.emission_interval / 4 < olsr_cnf->max_jitter)
+    olsr_cnf->max_jitter = IntConf->cnf->hello_params.emission_interval / 4;
 
-  if(max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
-    max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
+  if(olsr_cnf->max_tc_vtime < IntConf->cnf->tc_params.emission_interval)
+    olsr_cnf->max_tc_vtime = IntConf->cnf->tc_params.emission_interval;
 
-  New->hello_etime =
-    double_to_me(IntConf->cnf->hello_params.emission_interval);
+  New->hello_etime = IntConf->cnf->hello_params.emission_interval;
 
   New->valtimes.hello = double_to_me(IntConf->cnf->hello_params.validity_time);
   New->valtimes.tc = double_to_me(IntConf->cnf->tc_params.validity_time);
   New->valtimes.mid = double_to_me(IntConf->cnf->mid_params.validity_time);
   New->valtimes.hna = double_to_me(IntConf->cnf->hna_params.validity_time);
 
-  for (Walker = ifchgf_list; Walker != NULL; Walker = Walker->next)
-    Walker->function(New, IFCHG_IF_ADD);
+  run_ifchg_cbs(New, IFCHG_IF_ADD);
 
   return 1;
 }
@@ -832,11 +1017,17 @@ void check_interface_updates(void *dummy)
   struct olsr_if *IntConf;
 
 #ifdef DEBUG
-  olsr_printf(3, "Checking for updates in the interface set\n");
+  OLSR_PRINTF(3, "Checking for updates in the interface set\n")
 #endif
 
   for(IntConf = olsr_cnf->interfaces; IntConf != NULL; IntConf = IntConf->next)
   {
+    if(IntConf->host_emul)
+      continue;
+      
+    if(olsr_cnf->host_emul) /* XXX: TEMPORARY! */
+      continue;
     if(IntConf->configured)    
       chk_if_changed(IntConf);