Duplicate IP level check based on hash
authorunknown <nbs@.(none)>
Tue, 9 Mar 2010 09:13:39 +0000 (10:13 +0100)
committerunknown <nbs@.(none)>
Tue, 9 Mar 2010 09:13:39 +0000 (10:13 +0100)
lib/p2pd/src/NetworkInterfaces.c
lib/p2pd/src/NetworkInterfaces.h
lib/p2pd/src/Packet.c
lib/p2pd/src/Packet.h
lib/p2pd/src/PacketHistory.c [new file with mode: 0644]
lib/p2pd/src/PacketHistory.h [new file with mode: 0644]
lib/p2pd/src/dllist.c
lib/p2pd/src/dllist.h
lib/p2pd/src/olsrd_plugin.c
lib/p2pd/src/p2pd.c
lib/p2pd/src/p2pd.h

index c767b16..164334d 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-
-#include "NetworkInterfaces.h"
-
-/* System includes */
-#include <stddef.h>             /* NULL */
-#include <syslog.h>             /* syslog() */
-#include <string.h>             /* strerror(), strchr(), strcmp() */
-#include <errno.h>              /* errno */
-#include <unistd.h>             /* close() */
-#include <sys/ioctl.h>          /* ioctl() */
-#include <fcntl.h>              /* fcntl() */
-#include <assert.h>             /* assert() */
-#include <net/if.h>             /* socket(), ifreq, if_indextoname(), if_nametoindex() */
-#include <netinet/in.h>         /* htons() */
-#include <linux/if_ether.h>     /* ETH_P_IP */
-#include <linux/if_packet.h>    /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
-#include <linux/if_tun.h>       /* IFF_TAP */
-#include <netinet/ip.h>         /* struct ip */
-#include <netinet/udp.h>        /* SOL_UDP */
-#include <stdlib.h>             /* atoi, malloc */
-
-/* OLSRD includes */
-#include "olsr.h"               /* OLSR_PRINTF() */
-#include "ipcalc.h"
-#include "defs.h"               /* olsr_cnf */
-#include "link_set.h"           /* get_link_set() */
-#include "tc_set.h"             /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
-#include "net_olsr.h"           /* ipequal */
-#include "lq_plugin.h"
-//#include "olsr_ip_prefix_list.h"
-
-/* Plugin includes */
-#include "Packet.h"             /* IFHWADDRLEN */
-#include "p2pd.h"               /* PLUGIN_NAME, MainAddressOf() */
-//#include "Address.h"            /* IsMulticast() */
-
-
-/* List of network interface objects used by BMF plugin */
-struct NonOlsrInterface *nonOlsrInterfaces = NULL;
-struct NonOlsrInterface *lastNonOlsrInterface = NULL;
-
-/* -------------------------------------------------------------------------
- * Function   : CreateCaptureSocket
- * Description: Create socket for promiscuously capturing multicast IP traffic
- * Input      : ifname - network interface (e.g. "eth0")
- * Output     : none
- * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
- * Data Used  : none
- * Notes      : The socket is a cooked IP packet socket, bound to the specified
- *              network interface
- * ------------------------------------------------------------------------- */
-int
-CreateCaptureSocket(const char *ifName)
-{
-  int ifIndex = if_nametoindex(ifName);
-  struct packet_mreq mreq;
-  struct ifreq req;
-  struct sockaddr_ll bindTo;
-  int skfd = 0;
-  /* Open cooked IP packet socket */
-  if (olsr_cnf->ip_version == AF_INET) {
-    skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
-  } else {
-    skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
-  }
-  if (skfd < 0) {
-    P2pdPError("socket(PF_PACKET) error");
-    return -1;
-  }
-
-  /* Set interface to promiscuous mode */
-  memset(&mreq, 0, sizeof(struct packet_mreq));
-  mreq.mr_ifindex = ifIndex;
-  mreq.mr_type = PACKET_MR_PROMISC;
-  if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
-    P2pdPError("setsockopt(PACKET_MR_PROMISC) error");
-    close(skfd);
-    return -1;
-  }
-
-  /* Get hardware (MAC) address */
-  memset(&req, 0, sizeof(struct ifreq));
-  strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
-  req.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */
-  if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {
-    P2pdPError("error retrieving MAC address");
-    close(skfd);
-    return -1;
-  }
-
-  /* Bind the socket to the specified interface */
-  memset(&bindTo, 0, sizeof(bindTo));
-  bindTo.sll_family = AF_PACKET;
-  if (olsr_cnf->ip_version == AF_INET) {
-    bindTo.sll_protocol = htons(ETH_P_IP);
-  } else {
-    bindTo.sll_protocol = htons(ETH_P_IPV6);
-  }
-  bindTo.sll_ifindex = ifIndex;
-  memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
-  bindTo.sll_halen = IFHWADDRLEN;
-
-  if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
-    P2pdPError("bind() error");
-    close(skfd);
-    return -1;
-  }
-
-  /* Set socket to blocking operation */
-  if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
-    P2pdPError("fcntl() error");
-    close(skfd);
-    return -1;
-  }
-  //AddDescriptorToInputSet(skfd);
-  add_olsr_socket(skfd, (socket_handler_func)&DoP2pd, NULL, NULL, SP_PR_READ);
-
-  return skfd;
-}                               /* CreateCaptureSocket */
-
-/* -------------------------------------------------------------------------
- * Function   : CreateInterface
- * Description: Create a new NonOlsrInterface object and adds it to the global
- *              nonOlsrInterfaces list
- * Input      : ifName - name of the network interface (e.g. "eth0")
- *            : olsrIntf - OLSR interface object of the network interface, or
- *                NULL if the network interface is not OLSR-enabled
- * Output     : none
- * Return     : the number of opened sockets
- * Data Used  : nonOlsrInterfaces, lastNonOlsrInterface
- * ------------------------------------------------------------------------- */
-
-//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
-
-static int
-CreateInterface(const char *ifName, struct interface *olsrIntf)
-{
-  int capturingSkfd = -1;
-  int encapsulatingSkfd = -1;
-  int listeningSkfd = -1;
-  int ioctlSkfd;
-  struct ifreq ifr;
-  int nOpened = 0;
-  struct NonOlsrInterface *newIf = malloc(sizeof(struct NonOlsrInterface));
-
-  assert(ifName != NULL);
-
-  if (newIf == NULL) {
-    return 0;
-  }
-//TODO: assert interface is not talking OLSR
-
-
-  /* Create socket for capturing and sending of multicast packets on
-   * non-OLSR interfaces, and on OLSR-interfaces if configured. */
-  if ((olsrIntf == NULL)) {
-    capturingSkfd = CreateCaptureSocket(ifName);
-    if (capturingSkfd < 0) {
-      close(encapsulatingSkfd);
-      free(newIf);
-      return 0;
-    }
-
-    nOpened++;
-  }
-
-  /* For ioctl operations on the network interface, use either capturingSkfd
-   * or encapsulatingSkfd, whichever is available */
-  ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
-
-  /* Retrieve the MAC address of the interface. */
-  memset(&ifr, 0, sizeof(struct ifreq));
-  strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
-  ifr.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */
-  if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0) {
-    P2pdPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
-    close(capturingSkfd);
-    close(encapsulatingSkfd);
-    free(newIf);
-    return 0;
-  }
-
-  /* Copy data into NonOlsrInterface object */
-  newIf->capturingSkfd = capturingSkfd;
-  newIf->encapsulatingSkfd = encapsulatingSkfd;
-  newIf->listeningSkfd = listeningSkfd;
-  memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
-  memcpy(newIf->ifName, ifName, IFNAMSIZ);
-  newIf->olsrIntf = olsrIntf;
-  if (olsrIntf != NULL) {
-    /* For an OLSR-interface, copy the interface address and broadcast
-     * address from the OLSR interface object. Downcast to correct sockaddr
-     * subtype. */
-    newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
-    newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
-  } else {
-    /* For a non-OLSR interface, retrieve the IP address ourselves */
-    memset(&ifr, 0, sizeof(struct ifreq));
-    strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
-    ifr.ifr_name[IFNAMSIZ - 1] = '\0';  /* Ensures null termination */
-    if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) {
-      P2pdPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
-
-      newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
-    } else {
-      /* Downcast to correct sockaddr subtype */
-      newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
-    }
-
-    /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
-    memset(&ifr, 0, sizeof(struct ifreq));
-    strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
-    ifr.ifr_name[IFNAMSIZ - 1] = '\0';  /* Ensures null termination */
-    if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) {
-      P2pdPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
-
-      newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
-    } else {
-      /* Downcast to correct sockaddr subtype */
-      newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
-    }
-  }
-
-  /* Initialize fragment history table */
-  //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
-  //newIf->nextFragmentHistoryEntry = 0;
-
-  /* Reset counters */
-  //newIf->nNonOlsrPacketsRx = 0;
-  //newIf->nNonOlsrPacketsRxDup = 0;
-  //newIf->nNonOlsrPacketsTx = 0;
-
-  /* Add new NonOlsrInterface object to global list. OLSR interfaces are
-   * added at the front of the list, non-OLSR interfaces at the back. */
-  if (nonOlsrInterfaces == NULL) {
-    /* First NonOlsrInterface object in list */
-    nonOlsrInterfaces = newIf;
-    lastNonOlsrInterface = newIf;
-  } else if (olsrIntf != NULL) {
-    /* Add new NonOlsrInterface object at front of list */
-    newIf->next = nonOlsrInterfaces;
-    nonOlsrInterfaces = newIf;
-  } else {
-    /* Add new NonOlsrInterface object at back of list */
-    newIf->next = NULL;
-    lastNonOlsrInterface->next = newIf;
-    lastNonOlsrInterface = newIf;
-  }
-
-  //OLSR_PRINTF(
-  //  8,
-  //  "%s: opened %d socket%s on %s interface \"%s\"\n",
-  //  PLUGIN_NAME_SHORT,
-  //  nOpened,
-  //  nOpened == 1 ? "" : "s",
-  //  olsrIntf != NULL ? "OLSR" : "non-OLSR",
-  //  ifName);
-
-  return nOpened;
-}                               /* CreateInterface */
-
-/* -------------------------------------------------------------------------
- * Function   : CreateNonOlsrNetworkInterfaces
- * Description: Create a list of NonOlsrInterface objects, one for each network
- *              interface on which BMF runs
- * Input      : skipThisIntf - network interface to skip, if seen
- * Output     : none
- * Return     : fail (-1) or success (0)
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-int
-CreateNonOlsrNetworkInterfaces(struct interface *skipThisIntf)
-{
-  int skfd;
-  struct ifconf ifc;
-  int numreqs = 30;
-  struct ifreq *ifr;
-  int n;
-  int nOpenedSockets = 0;
-
-  /* Clear input descriptor set */
-  FD_ZERO(&InputSet);
-
-  skfd = socket(PF_INET, SOCK_DGRAM, 0);
-  if (skfd < 0) {
-    P2pdPError("no inet socket available to retrieve interface list");
-    return -1;
-  }
-
-  /* Retrieve the network interface configuration list */
-  ifc.ifc_buf = NULL;
-  for (;;) {
-    ifc.ifc_len = sizeof(struct ifreq) * numreqs;
-    ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
-
-    if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
-      P2pdPError("ioctl(SIOCGIFCONF) error");
-
-      close(skfd);
-      free(ifc.ifc_buf);
-      return -1;
-    }
-    if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
-      /* Assume it overflowed; double the space and try again */
-      numreqs *= 2;
-      assert(numreqs < 1024);
-      continue;                 /* for (;;) */
-    }
-    break;                      /* for (;;) */
-  }                             /* for (;;) */
-
-  close(skfd);
-
-  /* For each item in the interface configuration list... */
-  ifr = ifc.ifc_req;
-  for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++) {
-    struct interface *olsrIntf;
-    union olsr_ip_addr ipAddr;
-
-    /* Skip the BMF network interface itself */
-    //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
-    //{
-    //  continue; /* for (n = ...) */
-    //}
-
-    /* ...find the OLSR interface structure, if any */
-    ipAddr.v4 = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
-    olsrIntf = if_ifwithaddr(&ipAddr);
-
-    if (skipThisIntf != NULL && olsrIntf == skipThisIntf) {
-      continue;                 /* for (n = ...) */
-    }
-
-    if (olsrIntf == NULL && !IsNonOlsrIf(ifr->ifr_name)) {
-      /* Interface is neither OLSR interface, nor specified as non-OLSR
-       * interface in the plugin parameter list */
-      continue;                 /* for (n = ...) */
-    }
-
-    if (!IsNonOlsrIf(ifr->ifr_name)) {
-      //If the interface is not specified in the configuration file then go ahead
-      continue;                 /* for (n = ...) */
-    }
-    //TODO: asser if->ifr_name is not talking OLSR
-    //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
-    nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
-
-  }                             /* for (n = ...) */
-
-  free(ifc.ifc_buf);
-
-  if (nonOlsrInterfaces == NULL) {
-    //OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
-  } else {
-    //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
-  }
-  return 0;
-}                               /* CreateNonOlsrNetworkInterfaces */
-
-/* -------------------------------------------------------------------------
- * Function   : AddInterface
- * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
- *              network interfaces
- * Input      : newIntf - network interface to add
- * Output     : none
- * Return     : none
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-void
-AddInterface(struct interface *newIntf)
-{
-  int nOpened;
-
-  assert(newIntf != NULL);
-
-  nOpened = CreateInterface(newIntf->int_name, newIntf);
-
-  //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
-}                               /* AddInterface */
-
-/* -------------------------------------------------------------------------
- * Function   : CloseNonOlsrNetworkInterfaces
- * Description: Closes every socket on each network interface used by BMF
- * Input      : none
- * Output     : none
- * Return     : none
- * Data Used  : none
- * Notes      : Closes
- *              - the local EtherTunTap interface (e.g. "tun0" or "tap0")
- *              - for each BMF-enabled interface, the socket used for
- *                capturing multicast packets
- *              - for each OLSR-enabled interface, the socket used for
- *                encapsulating packets
- *              Also restores the network state to the situation before BMF
- *              was started.
- * ------------------------------------------------------------------------- */
-void
-CloseNonOlsrNetworkInterfaces(void)
-{
-  int nClosed = 0;
-  u_int32_t totalOlsrPacketsRx = 0;
-  u_int32_t totalOlsrPacketsRxDup = 0;
-  u_int32_t totalOlsrPacketsTx = 0;
-  u_int32_t totalNonOlsrPacketsRx = 0;
-  u_int32_t totalNonOlsrPacketsRxDup = 0;
-  u_int32_t totalNonOlsrPacketsTx = 0;
-
-  /* Close all opened sockets */
-  struct NonOlsrInterface *nextIf = nonOlsrInterfaces;
-  while (nextIf != NULL) {
-    struct NonOlsrInterface *ifc = nextIf;
-    nextIf = ifc->next;
-
-    if (ifc->capturingSkfd >= 0) {
-      close(ifc->capturingSkfd);
-      nClosed++;
-    }
-    if (ifc->encapsulatingSkfd >= 0) {
-      close(ifc->encapsulatingSkfd);
-      nClosed++;
-    }
-    //OLSR_PRINTF(
-    //  7,
-    //  "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
-    //  PLUGIN_NAME_SHORT,
-    //  ifc->olsrIntf != NULL ? "OLSR" : "non-OLSR",
-    //  ifc->ifName,
-    //  ifc->nPacketsRx,
-    //  ifc->nPacketsRxDup,
-    //  ifc->nPacketsTx);
-
-    //OLSR_PRINTF(
-    //  1,
-    //  "%s: closed %s interface \"%s\"\n",
-    //  PLUGIN_NAME_SHORT,
-    //  ifc->olsrIntf != NULL ? "OLSR" : "non-OLSR",
-    //  ifc->ifName);
-
-    /* Add totals */
-    if (ifc->olsrIntf != NULL) {
-      totalOlsrPacketsRx                               += ifc->nPacketsRx;
-      totalOlsrPacketsRxDup                    += ifc->nPacketsRxDup;
-      totalOlsrPacketsTx                               += ifc->nPacketsTx;
-    } else {
-      totalNonOlsrPacketsRx            += ifc->nPacketsRx;
-      totalNonOlsrPacketsRxDup += ifc->nPacketsRxDup;
-      totalNonOlsrPacketsTx                    += ifc->nPacketsTx;
-    }
-
-    free(ifc);
-  }                             /* while */
-
-  nonOlsrInterfaces = NULL;
-
-  //OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
-
-}                               /* CloseNonOlsrNetworkInterfaces */
-
-#define MAX_NON_OLSR_IFS 32
-static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
-static int nNonOlsrIfs = 0;
-/* -------------------------------------------------------------------------
- * Function   : AddNonOlsrIf
- * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
- *              network interfaces
- * Input      : ifName - network interface (e.g. "eth0")
- *              data - not used
- *              addon - not used
- * Output     : none
- * Return     : success (0) or fail (1)
- * Data Used  : NonOlsrIfNames
- * ------------------------------------------------------------------------- */
-int
-AddNonOlsrIf(const char *ifName, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
-{
-  assert(ifName != NULL);
-
-  if (nNonOlsrIfs >= MAX_NON_OLSR_IFS) {
-    //OLSR_PRINTF(
-    //  1,
-    //  "%s: too many non-OLSR interfaces specified, maximum is %d\n",
-    //  PLUGIN_NAME,
-    //  MAX_NON_OLSR_IFS);
-    return 1;
-  }
-
-  olsr_printf(1, "\nAdding interface '%s' to list of interface\n", ifName);
-  
-  strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
-  NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0';     /* Ensures null termination */
-  nNonOlsrIfs++;
-  return 0;
-}                               /* AddNonOlsrIf */
-
-/* -------------------------------------------------------------------------
- * Function   : IsNonOlsrIf
- * Description: Checks if a network interface is OLSR-enabled
- * Input      : ifName - network interface (e.g. "eth0")
- * Output     : none
- * Return     : true (1) or false (0)
- * Data Used  : NonOlsrIfNames
- * ------------------------------------------------------------------------- */
-int
-IsNonOlsrIf(const char *ifName)
-{
-  int i;
-
-  assert(ifName != NULL);
-
-  for (i = 0; i < nNonOlsrIfs; i++) {
-    if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0)
-      return 1;
-  }
-  return 0;
-}                               /* IsNonOlsrIf */
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+\r
+#include "NetworkInterfaces.h"\r
+\r
+/* System includes */\r
+#include <stddef.h>             /* NULL */\r
+#include <syslog.h>             /* syslog() */\r
+#include <string.h>             /* strerror(), strchr(), strcmp() */\r
+#include <errno.h>              /* errno */\r
+#include <unistd.h>             /* close() */\r
+#include <sys/ioctl.h>          /* ioctl() */\r
+#include <fcntl.h>              /* fcntl() */\r
+#include <assert.h>             /* assert() */\r
+#include <net/if.h>             /* socket(), ifreq, if_indextoname(), if_nametoindex() */\r
+#include <netinet/in.h>         /* htons() */\r
+#include <linux/if_ether.h>     /* ETH_P_IP */\r
+#include <linux/if_packet.h>    /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */\r
+#include <linux/if_tun.h>       /* IFF_TAP */\r
+#include <netinet/ip.h>         /* struct ip */\r
+#include <netinet/udp.h>        /* SOL_UDP */\r
+#include <stdlib.h>             /* atoi, malloc */\r
+\r
+/* OLSRD includes */\r
+#include "olsr.h"               /* OLSR_PRINTF() */\r
+#include "ipcalc.h"\r
+#include "defs.h"               /* olsr_cnf */\r
+#include "link_set.h"           /* get_link_set() */\r
+#include "tc_set.h"             /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */\r
+#include "net_olsr.h"           /* ipequal */\r
+#include "lq_plugin.h"\r
+//#include "olsr_ip_prefix_list.h"\r
+\r
+/* Plugin includes */\r
+#include "Packet.h"             /* IFHWADDRLEN */\r
+#include "p2pd.h"               /* PLUGIN_NAME, MainAddressOf() */\r
+//#include "Address.h"            /* IsMulticast() */\r
+\r
+\r
+/* List of network interface objects used by BMF plugin */\r
+struct NonOlsrInterface *nonOlsrInterfaces = NULL;\r
+struct NonOlsrInterface *lastNonOlsrInterface = NULL;\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CreateCaptureSocket\r
+ * Description: Create socket for promiscuously capturing multicast IP traffic\r
+ * Input      : ifname - network interface (e.g. "eth0")\r
+ * Output     : none\r
+ * Return     : the socket descriptor ( >= 0), or -1 if an error occurred\r
+ * Data Used  : none\r
+ * Notes      : The socket is a cooked IP packet socket, bound to the specified\r
+ *              network interface\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+CreateCaptureSocket(const char *ifName)\r
+{\r
+  int ifIndex = if_nametoindex(ifName);\r
+  struct packet_mreq mreq;\r
+  struct ifreq req;\r
+  struct sockaddr_ll bindTo;\r
+  int skfd = 0;\r
+  /* Open cooked IP packet socket */\r
+  if (olsr_cnf->ip_version == AF_INET) {\r
+    skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));\r
+  } else {\r
+    skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));\r
+  }\r
+  if (skfd < 0) {\r
+    P2pdPError("socket(PF_PACKET) error");\r
+    return -1;\r
+  }\r
+\r
+  /* Set interface to promiscuous mode */\r
+  memset(&mreq, 0, sizeof(struct packet_mreq));\r
+  mreq.mr_ifindex = ifIndex;\r
+  mreq.mr_type = PACKET_MR_PROMISC;\r
+  if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {\r
+    P2pdPError("setsockopt(PACKET_MR_PROMISC) error");\r
+    close(skfd);\r
+    return -1;\r
+  }\r
+\r
+  /* Get hardware (MAC) address */\r
+  memset(&req, 0, sizeof(struct ifreq));\r
+  strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);\r
+  req.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */\r
+  if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {\r
+    P2pdPError("error retrieving MAC address");\r
+    close(skfd);\r
+    return -1;\r
+  }\r
+\r
+  /* Bind the socket to the specified interface */\r
+  memset(&bindTo, 0, sizeof(bindTo));\r
+  bindTo.sll_family = AF_PACKET;\r
+  if (olsr_cnf->ip_version == AF_INET) {\r
+    bindTo.sll_protocol = htons(ETH_P_IP);\r
+  } else {\r
+    bindTo.sll_protocol = htons(ETH_P_IPV6);\r
+  }\r
+  bindTo.sll_ifindex = ifIndex;\r
+  memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);\r
+  bindTo.sll_halen = IFHWADDRLEN;\r
+\r
+  if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {\r
+    P2pdPError("bind() error");\r
+    close(skfd);\r
+    return -1;\r
+  }\r
+\r
+  /* Set socket to blocking operation */\r
+  if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {\r
+    P2pdPError("fcntl() error");\r
+    close(skfd);\r
+    return -1;\r
+  }\r
+  //AddDescriptorToInputSet(skfd);\r
+  add_olsr_socket(skfd, (socket_handler_func)&DoP2pd, NULL, NULL, SP_PR_READ);\r
+\r
+  return skfd;\r
+}                               /* CreateCaptureSocket */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CreateInterface\r
+ * Description: Create a new NonOlsrInterface object and adds it to the global\r
+ *              nonOlsrInterfaces list\r
+ * Input      : ifName - name of the network interface (e.g. "eth0")\r
+ *            : olsrIntf - OLSR interface object of the network interface, or\r
+ *                NULL if the network interface is not OLSR-enabled\r
+ * Output     : none\r
+ * Return     : the number of opened sockets\r
+ * Data Used  : nonOlsrInterfaces, lastNonOlsrInterface\r
+ * ------------------------------------------------------------------------- */\r
+\r
+//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG\r
+\r
+static int\r
+CreateInterface(const char *ifName, struct interface *olsrIntf)\r
+{\r
+  int capturingSkfd = -1;\r
+  int encapsulatingSkfd = -1;\r
+  int listeningSkfd = -1;\r
+  int ioctlSkfd;\r
+  struct ifreq ifr;\r
+  int nOpened = 0;\r
+  struct NonOlsrInterface *newIf = malloc(sizeof(struct NonOlsrInterface));\r
+\r
+  assert(ifName != NULL);\r
+\r
+  if (newIf == NULL) {\r
+    return 0;\r
+  }\r
+//TODO: assert interface is not talking OLSR\r
+\r
+\r
+  /* Create socket for capturing and sending of multicast packets on\r
+   * non-OLSR interfaces, and on OLSR-interfaces if configured. */\r
+  if ((olsrIntf == NULL)) {\r
+    capturingSkfd = CreateCaptureSocket(ifName);\r
+    if (capturingSkfd < 0) {\r
+      close(encapsulatingSkfd);\r
+      free(newIf);\r
+      return 0;\r
+    }\r
+\r
+    nOpened++;\r
+  }\r
+\r
+  /* For ioctl operations on the network interface, use either capturingSkfd\r
+   * or encapsulatingSkfd, whichever is available */\r
+  ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;\r
+\r
+  /* Retrieve the MAC address of the interface. */\r
+  memset(&ifr, 0, sizeof(struct ifreq));\r
+  strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);\r
+  ifr.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */\r
+  if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0) {\r
+    P2pdPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);\r
+    close(capturingSkfd);\r
+    close(encapsulatingSkfd);\r
+    free(newIf);\r
+    return 0;\r
+  }\r
+\r
+  /* Copy data into NonOlsrInterface object */\r
+  newIf->capturingSkfd = capturingSkfd;\r
+  newIf->encapsulatingSkfd = encapsulatingSkfd;\r
+  newIf->listeningSkfd = listeningSkfd;\r
+  memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);\r
+  memcpy(newIf->ifName, ifName, IFNAMSIZ);\r
+  newIf->olsrIntf = olsrIntf;\r
+  if (olsrIntf != NULL) {\r
+    /* For an OLSR-interface, copy the interface address and broadcast\r
+     * address from the OLSR interface object. Downcast to correct sockaddr\r
+     * subtype. */\r
+    newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;\r
+    newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;\r
+  } else {\r
+    /* For a non-OLSR interface, retrieve the IP address ourselves */\r
+    memset(&ifr, 0, sizeof(struct ifreq));\r
+    strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);\r
+    ifr.ifr_name[IFNAMSIZ - 1] = '\0';  /* Ensures null termination */\r
+    if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) {\r
+      P2pdPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);\r
+\r
+      newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");\r
+    } else {\r
+      /* Downcast to correct sockaddr subtype */\r
+      newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;\r
+    }\r
+\r
+    /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */\r
+    memset(&ifr, 0, sizeof(struct ifreq));\r
+    strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);\r
+    ifr.ifr_name[IFNAMSIZ - 1] = '\0';  /* Ensures null termination */\r
+    if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) {\r
+      P2pdPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);\r
+\r
+      newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");\r
+    } else {\r
+      /* Downcast to correct sockaddr subtype */\r
+      newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;\r
+    }\r
+  }\r
+\r
+  /* Initialize fragment history table */\r
+  //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));\r
+  //newIf->nextFragmentHistoryEntry = 0;\r
+\r
+  /* Reset counters */\r
+  //newIf->nNonOlsrPacketsRx = 0;\r
+  //newIf->nNonOlsrPacketsRxDup = 0;\r
+  //newIf->nNonOlsrPacketsTx = 0;\r
+\r
+  /* Add new NonOlsrInterface object to global list. OLSR interfaces are\r
+   * added at the front of the list, non-OLSR interfaces at the back. */\r
+  if (nonOlsrInterfaces == NULL) {\r
+    /* First NonOlsrInterface object in list */\r
+    nonOlsrInterfaces = newIf;\r
+    lastNonOlsrInterface = newIf;\r
+  } else if (olsrIntf != NULL) {\r
+    /* Add new NonOlsrInterface object at front of list */\r
+    newIf->next = nonOlsrInterfaces;\r
+    nonOlsrInterfaces = newIf;\r
+  } else {\r
+    /* Add new NonOlsrInterface object at back of list */\r
+    newIf->next = NULL;\r
+    lastNonOlsrInterface->next = newIf;\r
+    lastNonOlsrInterface = newIf;\r
+  }\r
+\r
+  //OLSR_PRINTF(\r
+  //  8,\r
+  //  "%s: opened %d socket%s on %s interface \"%s\"\n",\r
+  //  PLUGIN_NAME_SHORT,\r
+  //  nOpened,\r
+  //  nOpened == 1 ? "" : "s",\r
+  //  olsrIntf != NULL ? "OLSR" : "non-OLSR",\r
+  //  ifName);\r
+\r
+  return nOpened;\r
+}                               /* CreateInterface */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CreateNonOlsrNetworkInterfaces\r
+ * Description: Create a list of NonOlsrInterface objects, one for each network\r
+ *              interface on which BMF runs\r
+ * Input      : skipThisIntf - network interface to skip, if seen\r
+ * Output     : none\r
+ * Return     : fail (-1) or success (0)\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+CreateNonOlsrNetworkInterfaces(struct interface *skipThisIntf)\r
+{\r
+  int skfd;\r
+  struct ifconf ifc;\r
+  int numreqs = 30;\r
+  struct ifreq *ifr;\r
+  int n;\r
+  int nOpenedSockets = 0;\r
+\r
+  /* Clear input descriptor set */\r
+  FD_ZERO(&InputSet);\r
+\r
+  skfd = socket(PF_INET, SOCK_DGRAM, 0);\r
+  if (skfd < 0) {\r
+    P2pdPError("no inet socket available to retrieve interface list");\r
+    return -1;\r
+  }\r
+\r
+  /* Retrieve the network interface configuration list */\r
+  ifc.ifc_buf = NULL;\r
+  for (;;) {\r
+    ifc.ifc_len = sizeof(struct ifreq) * numreqs;\r
+    ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);\r
+\r
+    if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {\r
+      P2pdPError("ioctl(SIOCGIFCONF) error");\r
+\r
+      close(skfd);\r
+      free(ifc.ifc_buf);\r
+      return -1;\r
+    }\r
+    if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs) {\r
+      /* Assume it overflowed; double the space and try again */\r
+      numreqs *= 2;\r
+      assert(numreqs < 1024);\r
+      continue;                 /* for (;;) */\r
+    }\r
+    break;                      /* for (;;) */\r
+  }                             /* for (;;) */\r
+\r
+  close(skfd);\r
+\r
+  /* For each item in the interface configuration list... */\r
+  ifr = ifc.ifc_req;\r
+  for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++) {\r
+    struct interface *olsrIntf;\r
+    union olsr_ip_addr ipAddr;\r
+\r
+    /* Skip the BMF network interface itself */\r
+    //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)\r
+    //{\r
+    //  continue; /* for (n = ...) */\r
+    //}\r
+\r
+    /* ...find the OLSR interface structure, if any */\r
+    ipAddr.v4 = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;\r
+    olsrIntf = if_ifwithaddr(&ipAddr);\r
+\r
+    if (skipThisIntf != NULL && olsrIntf == skipThisIntf) {\r
+      continue;                 /* for (n = ...) */\r
+    }\r
+\r
+    if (olsrIntf == NULL && !IsNonOlsrIf(ifr->ifr_name)) {\r
+      /* Interface is neither OLSR interface, nor specified as non-OLSR\r
+       * interface in the plugin parameter list */\r
+      continue;                 /* for (n = ...) */\r
+    }\r
+\r
+    if (!IsNonOlsrIf(ifr->ifr_name)) {\r
+      //If the interface is not specified in the configuration file then go ahead\r
+      continue;                 /* for (n = ...) */\r
+    }\r
+    //TODO: asser if->ifr_name is not talking OLSR\r
+    //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);\r
+    nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);\r
+\r
+  }                             /* for (n = ...) */\r
+\r
+  free(ifc.ifc_buf);\r
+\r
+  if (nonOlsrInterfaces == NULL) {\r
+    //OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);\r
+  } else {\r
+    //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);\r
+  }\r
+  return 0;\r
+}                               /* CreateNonOlsrNetworkInterfaces */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : AddInterface\r
+ * Description: Add an OLSR-enabled network interface to the list of BMF-enabled\r
+ *              network interfaces\r
+ * Input      : newIntf - network interface to add\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+AddInterface(struct interface *newIntf)\r
+{\r
+  int nOpened;\r
+\r
+  assert(newIntf != NULL);\r
+\r
+  nOpened = CreateInterface(newIntf->int_name, newIntf);\r
+\r
+  //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);\r
+}                               /* AddInterface */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CloseNonOlsrNetworkInterfaces\r
+ * Description: Closes every socket on each network interface used by BMF\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * Notes      : Closes\r
+ *              - the local EtherTunTap interface (e.g. "tun0" or "tap0")\r
+ *              - for each BMF-enabled interface, the socket used for\r
+ *                capturing multicast packets\r
+ *              - for each OLSR-enabled interface, the socket used for\r
+ *                encapsulating packets\r
+ *              Also restores the network state to the situation before BMF\r
+ *              was started.\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+CloseNonOlsrNetworkInterfaces(void)\r
+{\r
+  int nClosed = 0;\r
+  u_int32_t totalOlsrPacketsRx = 0;\r
+  u_int32_t totalOlsrPacketsRxDup = 0;\r
+  u_int32_t totalOlsrPacketsTx = 0;\r
+  u_int32_t totalNonOlsrPacketsRx = 0;\r
+  u_int32_t totalNonOlsrPacketsRxDup = 0;\r
+  u_int32_t totalNonOlsrPacketsTx = 0;\r
+\r
+  /* Close all opened sockets */\r
+  struct NonOlsrInterface *nextIf = nonOlsrInterfaces;\r
+  while (nextIf != NULL) {\r
+    struct NonOlsrInterface *ifc = nextIf;\r
+    nextIf = ifc->next;\r
+\r
+    if (ifc->capturingSkfd >= 0) {\r
+      close(ifc->capturingSkfd);\r
+      nClosed++;\r
+    }\r
+    if (ifc->encapsulatingSkfd >= 0) {\r
+      close(ifc->encapsulatingSkfd);\r
+      nClosed++;\r
+    }\r
+    //OLSR_PRINTF(\r
+    //  7,\r
+    //  "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",\r
+    //  PLUGIN_NAME_SHORT,\r
+    //  ifc->olsrIntf != NULL ? "OLSR" : "non-OLSR",\r
+    //  ifc->ifName,\r
+    //  ifc->nPacketsRx,\r
+    //  ifc->nPacketsRxDup,\r
+    //  ifc->nPacketsTx);\r
+\r
+    //OLSR_PRINTF(\r
+    //  1,\r
+    //  "%s: closed %s interface \"%s\"\n",\r
+    //  PLUGIN_NAME_SHORT,\r
+    //  ifc->olsrIntf != NULL ? "OLSR" : "non-OLSR",\r
+    //  ifc->ifName);\r
+\r
+    /* Add totals */\r
+    if (ifc->olsrIntf != NULL) {\r
+      totalOlsrPacketsRx                               += ifc->nPacketsRx;\r
+      totalOlsrPacketsRxDup                    += ifc->nPacketsRxDup;\r
+      totalOlsrPacketsTx                               += ifc->nPacketsTx;\r
+    } else {\r
+      totalNonOlsrPacketsRx            += ifc->nPacketsRx;\r
+      totalNonOlsrPacketsRxDup += ifc->nPacketsRxDup;\r
+      totalNonOlsrPacketsTx                    += ifc->nPacketsTx;\r
+    }\r
+\r
+    free(ifc);\r
+  }                             /* while */\r
+\r
+  nonOlsrInterfaces = NULL;\r
+\r
+  //OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);\r
+\r
+}                               /* CloseNonOlsrNetworkInterfaces */\r
+\r
+#define MAX_NON_OLSR_IFS 32\r
+static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];\r
+static int nNonOlsrIfs = 0;\r
+/* -------------------------------------------------------------------------\r
+ * Function   : AddNonOlsrIf\r
+ * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled\r
+ *              network interfaces\r
+ * Input      : ifName - network interface (e.g. "eth0")\r
+ *              data - not used\r
+ *              addon - not used\r
+ * Output     : none\r
+ * Return     : success (0) or fail (1)\r
+ * Data Used  : NonOlsrIfNames\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+AddNonOlsrIf(const char *ifName, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))\r
+{\r
+  assert(ifName != NULL);\r
+\r
+  if (nNonOlsrIfs >= MAX_NON_OLSR_IFS) {\r
+    //OLSR_PRINTF(\r
+    //  1,\r
+    //  "%s: too many non-OLSR interfaces specified, maximum is %d\n",\r
+    //  PLUGIN_NAME,\r
+    //  MAX_NON_OLSR_IFS);\r
+    return 1;\r
+  }\r
+\r
+  olsr_printf(1, "\nAdding interface '%s' to list of interface\n", ifName);\r
+  \r
+  strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);\r
+  NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0';     /* Ensures null termination */\r
+  nNonOlsrIfs++;\r
+  return 0;\r
+}                               /* AddNonOlsrIf */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : IsNonOlsrIf\r
+ * Description: Checks if a network interface is OLSR-enabled\r
+ * Input      : ifName - network interface (e.g. "eth0")\r
+ * Output     : none\r
+ * Return     : true (1) or false (0)\r
+ * Data Used  : NonOlsrIfNames\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+IsNonOlsrIf(const char *ifName)\r
+{\r
+  int i;\r
+\r
+  assert(ifName != NULL);\r
+\r
+  for (i = 0; i < nNonOlsrIfs; i++) {\r
+    if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0)\r
+      return 1;\r
+  }\r
+  return 0;\r
+}                               /* IsNonOlsrIf */\r
index 46a1a0b..1c65269 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-
-#ifndef _NETWORKINTERFACES_H
-#define _NETWORKINTERFACES_H
-
-/* System includes */
-#include <netinet/in.h>         /* struct in_addr */
-
-/* OLSR includes */
-#include "olsr_types.h"         /* olsr_ip_addr */
-#include "olsrd_plugin.h"             /* union set_plugin_parameter_addon */
-
-/* Plugin includes */
-#include "Packet.h"             /* IFHWADDRLEN */
-#include "p2pd.h"
-
-/* Size of buffer in which packets are received */
-#define P2PD_BUFFER_SIZE 2048
-
-struct NonOlsrInterface {
-  /* File descriptor of raw packet socket, used for capturing multicast packets */
-  int capturingSkfd;
-
-  /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
-   * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
-  int encapsulatingSkfd;
-
-  /* File descriptor of UDP packet socket, used for listening to encapsulation packets.
-   * Used only when PlParam "P2pdMechanism" is set to "UnicastPromiscuous". */
-  int listeningSkfd;
-
-  unsigned char macAddr[IFHWADDRLEN];
-
-  char ifName[IFNAMSIZ];
-
-  /* OLSRs idea of this network interface. NULL if this interface is not
-   * OLSR-enabled. */
-  struct interface *olsrIntf;
-
-  /* IP address of this network interface */
-  union olsr_ip_addr intAddr;
-
-  /* Broadcast address of this network interface */
-  union olsr_ip_addr broadAddr;
-
-#define FRAGMENT_HISTORY_SIZE 10
-  struct TFragmentHistory {
-    u_int16_t ipId;
-    u_int8_t ipProto;
-    struct in_addr ipSrc;
-    struct in_addr ipDst;
-  } fragmentHistory[FRAGMENT_HISTORY_SIZE];
-
-  int nextFragmentHistoryEntry;
-
-  /* Number of received and transmitted BMF packets on this interface */
-  u_int32_t nPacketsRx;
-  u_int32_t nPacketsRxDup;
-  u_int32_t nPacketsTx;
-
-  /* Next element in list */
-  struct NonOlsrInterface *next;
-};
-
-extern struct NonOlsrInterface *nonOlsrInterfaces;
-
-extern int HighestSkfd;
-extern fd_set InputSet;
-
-extern int EtherTunTapFd;
-
-extern char EtherTunTapIfName[];
-
-/* 10.255.255.253 in host byte order */
-#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD
-
-extern u_int32_t EtherTunTapIp;
-extern u_int32_t EtherTunTapIpMask;
-extern u_int32_t EtherTunTapIpBroadcast;
-
-
-enum P2pdMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
-extern enum P2pdMechanism P2pdMechanism;
-
-int SetNonOlsrInterfaceName(const char *ifname, void *data, set_plugin_parameter_addon addon);
-int SetNonOlsrInterfaceIp(const char *ip, void *data, set_plugin_parameter_addon addon);
-int SetCapturePacketsOnOlsrInterfaces(const char *enable, void *data, set_plugin_parameter_addon addon);
-int SetP2pdMechanism(const char *mechanism, void *data, set_plugin_parameter_addon addon);
-int DeactivateSpoofFilter(void);
-void RestoreSpoofFilter(void);
-
-#define MAX_UNICAST_NEIGHBORS 10
-struct TBestNeighbors {
-  struct link_entry *links[MAX_UNICAST_NEIGHBORS];
-};
-
-void FindNeighbors(struct TBestNeighbors *neighbors,
-                   struct link_entry **bestNeighbor,
-                   struct NonOlsrInterface *intf,
-                   union olsr_ip_addr *source,
-                   union olsr_ip_addr *forwardedBy, union olsr_ip_addr *forwardedTo, int *nPossibleNeighbors);
-
-int CreateNonOlsrNetworkInterfaces(struct interface *skipThisIntf);
-void AddInterface(struct interface *newIntf);
-void CloseNonOlsrNetworkInterfaces(void);
-int AddNonOlsrIf(const char *ifName, void *data, set_plugin_parameter_addon addon);
-int IsNonOlsrIf(const char *ifName);
-void CheckAndUpdateLocalBroadcast(unsigned char *ipPacket, union olsr_ip_addr *broadAddr);
-void AddMulticastRoute(void);
-void DeleteMulticastRoute(void);
-int CreateCaptureSocket(const char *ifName);
-
-#endif /* _BMF_NETWORKINTERFACES_H */
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _NETWORKINTERFACES_H\r
+#define _NETWORKINTERFACES_H\r
+\r
+/* System includes */\r
+#include <netinet/in.h>         /* struct in_addr */\r
+\r
+/* OLSR includes */\r
+#include "olsr_types.h"         /* olsr_ip_addr */\r
+#include "olsrd_plugin.h"             /* union set_plugin_parameter_addon */\r
+\r
+/* Plugin includes */\r
+#include "Packet.h"             /* IFHWADDRLEN */\r
+#include "p2pd.h"\r
+\r
+/* Size of buffer in which packets are received */\r
+#define P2PD_BUFFER_SIZE 2048\r
+\r
+struct NonOlsrInterface {\r
+  /* File descriptor of raw packet socket, used for capturing multicast packets */\r
+  int capturingSkfd;\r
+\r
+  /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.\r
+   * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */\r
+  int encapsulatingSkfd;\r
+\r
+  /* File descriptor of UDP packet socket, used for listening to encapsulation packets.\r
+   * Used only when PlParam "P2pdMechanism" is set to "UnicastPromiscuous". */\r
+  int listeningSkfd;\r
+\r
+  unsigned char macAddr[IFHWADDRLEN];\r
+\r
+  char ifName[IFNAMSIZ];\r
+\r
+  /* OLSRs idea of this network interface. NULL if this interface is not\r
+   * OLSR-enabled. */\r
+  struct interface *olsrIntf;\r
+\r
+  /* IP address of this network interface */\r
+  union olsr_ip_addr intAddr;\r
+\r
+  /* Broadcast address of this network interface */\r
+  union olsr_ip_addr broadAddr;\r
+\r
+#define FRAGMENT_HISTORY_SIZE 10\r
+  struct TFragmentHistory {\r
+    u_int16_t ipId;\r
+    u_int8_t ipProto;\r
+    struct in_addr ipSrc;\r
+    struct in_addr ipDst;\r
+  } fragmentHistory[FRAGMENT_HISTORY_SIZE];\r
+\r
+  int nextFragmentHistoryEntry;\r
+\r
+  /* Number of received and transmitted BMF packets on this interface */\r
+  u_int32_t nPacketsRx;\r
+  u_int32_t nPacketsRxDup;\r
+  u_int32_t nPacketsTx;\r
+\r
+  /* Next element in list */\r
+  struct NonOlsrInterface *next;\r
+};\r
+\r
+extern struct NonOlsrInterface *nonOlsrInterfaces;\r
+\r
+extern int HighestSkfd;\r
+extern fd_set InputSet;\r
+\r
+extern int EtherTunTapFd;\r
+\r
+extern char EtherTunTapIfName[];\r
+\r
+/* 10.255.255.253 in host byte order */\r
+#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD\r
+\r
+extern u_int32_t EtherTunTapIp;\r
+extern u_int32_t EtherTunTapIpMask;\r
+extern u_int32_t EtherTunTapIpBroadcast;\r
+\r
+\r
+enum P2pdMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };\r
+extern enum P2pdMechanism P2pdMechanism;\r
+\r
+int SetNonOlsrInterfaceName(const char *ifname, void *data, set_plugin_parameter_addon addon);\r
+int SetNonOlsrInterfaceIp(const char *ip, void *data, set_plugin_parameter_addon addon);\r
+int SetCapturePacketsOnOlsrInterfaces(const char *enable, void *data, set_plugin_parameter_addon addon);\r
+int SetP2pdMechanism(const char *mechanism, void *data, set_plugin_parameter_addon addon);\r
+int DeactivateSpoofFilter(void);\r
+void RestoreSpoofFilter(void);\r
+\r
+#define MAX_UNICAST_NEIGHBORS 10\r
+struct TBestNeighbors {\r
+  struct link_entry *links[MAX_UNICAST_NEIGHBORS];\r
+};\r
+\r
+void FindNeighbors(struct TBestNeighbors *neighbors,\r
+                   struct link_entry **bestNeighbor,\r
+                   struct NonOlsrInterface *intf,\r
+                   union olsr_ip_addr *source,\r
+                   union olsr_ip_addr *forwardedBy, union olsr_ip_addr *forwardedTo, int *nPossibleNeighbors);\r
+\r
+int CreateNonOlsrNetworkInterfaces(struct interface *skipThisIntf);\r
+void AddInterface(struct interface *newIntf);\r
+void CloseNonOlsrNetworkInterfaces(void);\r
+int AddNonOlsrIf(const char *ifName, void *data, set_plugin_parameter_addon addon);\r
+int IsNonOlsrIf(const char *ifName);\r
+void CheckAndUpdateLocalBroadcast(unsigned char *ipPacket, union olsr_ip_addr *broadAddr);\r
+void AddMulticastRoute(void);\r
+void DeleteMulticastRoute(void);\r
+int CreateCaptureSocket(const char *ifName);\r
+\r
+#endif /* _BMF_NETWORKINTERFACES_H */\r
+\r
+/*\r
+ * Local Variables:\r
+ * c-basic-offset: 2\r
+ * indent-tabs-mode: nil\r
+ * End:\r
+ */\r
index 011c0d1..9572275 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-#include "Packet.h"
-
-/* System includes */
-#include <stddef.h>             /* NULL */
-#include <assert.h>             /* assert() */
-#include <string.h>             /* memcpy() */
-#include <sys/types.h>          /* u_int8_t, u_int16_t, u_int32_t */
-#include <netinet/in.h>         /* ntohs(), htons() */
-#include <netinet/ip.h>         /* struct iphdr */
-
-/* -------------------------------------------------------------------------
- * Function   : IsIpv4Fragment
- * Description: Check if an IP packet is an IP fragment
- * Input      : ipPacket - the IP packet
- * Output     : none
- * Return     : true (1) or false (0)
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-int IsIpv4Fragment(struct ip* hdr)
-{
-  assert(hdr != NULL);
-
-  if ((ntohs(hdr->ip_off) & IP_OFFMASK) != 0)
-  {
-    return 1;
-  }
-  return 0;
-} /* IsIpv4Fragment */
-
-int IsMulticastv4(struct ip* hdr)
-{
-  uint32_t addr;
-
-  assert(hdr != NULL);
-
-  memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));
-  if ((addr & 0xE0000000) == 0xE0000000)
-    return 1;
-  
-  return 0;
-}
-
-int IsBroadcast(struct ip* hdr)
-{
-  uint32_t addr;
-
-  assert(hdr != NULL);
-
-  memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));
-  if (addr == 0xFFFFFFFF)
-    return 1;
-    
-  return 0;
-}
-
-/* -------------------------------------------------------------------------
- * Function   : IsIpv6Fragment
- * Description: Check if an IP packet is an IP fragment
- * Input      : ipPacket - the IP packet
- * Output     : none
- * Return     : true (1) or false (0)
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-int IsIpv6Fragment(struct ip6_hdr* hdr)
-{
-  assert(hdr != NULL);
-  
-//#error Implementation required
-  if (0)
-    return 1;
-    
-  return 0;
-}
-
-int IsMulticastv6(struct ip6_hdr* hdr)
-{
-  assert(hdr != NULL);
-
-
-  return 0;
-}
-
-/* -------------------------------------------------------------------------
- * Function   : GetIpHeaderLength
- * Description: Retrieve the IP header length (in bytes) of an IP packet
- * Input      : ipPacket - the IP packet
- * Output     : none
- * Return     : IP header length
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-unsigned int
-GetIpHeaderLength(unsigned char *ipPacket)
-{
-  struct iphdr *iph;
-
-  assert(ipPacket != NULL);
-
-  iph = (struct iphdr *)ipPacket;
-  return iph->ihl << 2;
-}                               /* GetIpHeaderLength */
-
-/* -------------------------------------------------------------------------
- * Function   : GetIpPacket
- * Description: Retrieve the IP packet from BMF encapsulation UDP data
- * Input      : encapsulationUdpData - the encapsulation UDP data
- * Output     : none
- * Return     : The IP packet
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-unsigned char *
-GetIpPacket(unsigned char *encapsulationUdpData)
-{
-  return encapsulationUdpData + ENCAP_HDR_LEN;
-}                               /* GetIpPacket */
-
-
-
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+#include "Packet.h"\r
+\r
+/* System includes */\r
+#include <stddef.h>             /* NULL */\r
+#include <assert.h>             /* assert() */\r
+#include <string.h>             /* memcpy() */\r
+#include <sys/types.h>          /* u_int8_t, u_int16_t, u_int32_t */\r
+#include <netinet/in.h>         /* ntohs(), htons() */\r
+#include <netinet/ip.h>         /* struct iphdr */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : IsIpFragment\r
+ * Description: Check if an IP packet is an IP fragment\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : true (1) or false (0)\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+int IsIpFragment(unsigned char* ipPacket)\r
+{\r
+  struct ip* iph;\r
+\r
+  assert(ipPacket != NULL);\r
+\r
+  iph = (struct ip*) ipPacket;\r
+  if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)\r
+  {\r
+    return 1;\r
+  }\r
+  return 0;\r
+} /* IsIpFragment */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : GetIpTotalLength\r
+ * Description: Retrieve the total length of the IP packet (in bytes) of\r
+ *              an IP packet\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : IP packet length\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+u_int16_t GetIpTotalLength(unsigned char* ipPacket)\r
+{\r
+  struct iphdr* iph;\r
+\r
+  assert(ipPacket != NULL);\r
+\r
+  iph = (struct iphdr*) ipPacket;\r
+  return ntohs(iph->tot_len);\r
+} /* GetIpTotalLength */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : IsIpv4Fragment\r
+ * Description: Check if an IP packet is an IP fragment\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : true (1) or false (0)\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+int IsIpv4Fragment(struct ip* hdr)\r
+{\r
+  assert(hdr != NULL);\r
+\r
+  if ((ntohs(hdr->ip_off) & IP_OFFMASK) != 0)\r
+  {\r
+    return 1;\r
+  }\r
+  return 0;\r
+} /* IsIpv4Fragment */\r
+\r
+int IsMulticastv4(struct ip* hdr)\r
+{\r
+  uint32_t addr;\r
+\r
+  assert(hdr != NULL);\r
+\r
+  memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));\r
+  if ((addr & 0xE0000000) == 0xE0000000)\r
+    return 1;\r
+  \r
+  return 0;\r
+}\r
+\r
+int IsBroadcast(struct ip* hdr)\r
+{\r
+  uint32_t addr;\r
+\r
+  assert(hdr != NULL);\r
+\r
+  memcpy(&addr, &hdr->ip_dst.s_addr, sizeof(addr));\r
+  if (addr == 0xFFFFFFFF)\r
+    return 1;\r
+    \r
+  return 0;\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : IsIpv6Fragment\r
+ * Description: Check if an IP packet is an IP fragment\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : true (1) or false (0)\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+int IsIpv6Fragment(struct ip6_hdr* hdr)\r
+{\r
+  assert(hdr != NULL);\r
+  \r
+//#error Implementation required\r
+  if (0)\r
+    return 1;\r
+    \r
+  return 0;\r
+}\r
+\r
+int IsMulticastv6(struct ip6_hdr* hdr)\r
+{\r
+  assert(hdr != NULL);\r
+\r
+\r
+  return 0;\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : GetIpHeaderLength\r
+ * Description: Retrieve the IP header length (in bytes) of an IP packet\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : IP header length\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+unsigned int\r
+GetIpHeaderLength(unsigned char *ipPacket)\r
+{\r
+  struct iphdr *iph;\r
+\r
+  assert(ipPacket != NULL);\r
+\r
+  iph = (struct iphdr *)ipPacket;\r
+  return iph->ihl << 2;\r
+}                               /* GetIpHeaderLength */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : GetIpPacket\r
+ * Description: Retrieve the IP packet from BMF encapsulation UDP data\r
+ * Input      : encapsulationUdpData - the encapsulation UDP data\r
+ * Output     : none\r
+ * Return     : The IP packet\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+unsigned char *\r
+GetIpPacket(unsigned char *encapsulationUdpData)\r
+{\r
+  return encapsulationUdpData + ENCAP_HDR_LEN;\r
+}                               /* GetIpPacket */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : GetTtl\r
+ * Description: Retrieve the TTL (Time To Live) value from the IP header of\r
+ *              an IP packet\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : TTL value\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+u_int8_t GetTtl(unsigned char* ipPacket)\r
+{\r
+  struct iphdr* iph;\r
+\r
+  assert(ipPacket != NULL);\r
+\r
+  iph = (struct iphdr*) ipPacket;\r
+  return iph->ttl;\r
+} /* GetTtl */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : SaveTtlAndChecksum\r
+ * Description: Save the TTL (Time To Live) value and IP checksum as found in\r
+ *              the IP header of an IP packet\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : sttl - the TTL and checksum values\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)\r
+{\r
+  struct iphdr* iph;\r
+\r
+  assert(ipPacket != NULL && sttl != NULL);\r
+\r
+  iph = (struct iphdr*) ipPacket;\r
+  sttl->ttl = iph->ttl;\r
+  sttl->check = ntohs(iph->check);\r
+} /* SaveTtlAndChecksum */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : RestoreTtlAndChecksum\r
+ * Description: Restore the TTL (Time To Live) value and IP checksum in\r
+ *              the IP header of an IP packet\r
+ * Input      : ipPacket - the IP packet\r
+ *              sttl - the TTL and checksum values\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)\r
+{\r
+  struct iphdr* iph;\r
+\r
+  assert(ipPacket != NULL && sttl != NULL);\r
+\r
+  iph = (struct iphdr*) ipPacket;\r
+  iph->ttl = sttl->ttl;\r
+  iph->check = htons(sttl->check);\r
+} /* RestoreTtlAndChecksum */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : DecreaseTtlAndUpdateHeaderChecksum\r
+ * Description: For an IP packet, decrement the TTL value and update the IP header\r
+ *              checksum accordingly.\r
+ * Input      : ipPacket - the IP packet\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * Notes      : See also RFC1141\r
+ * ------------------------------------------------------------------------- */\r
+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)\r
+{\r
+  struct iphdr* iph;\r
+  u_int32_t sum;\r
+\r
+  assert(ipPacket != NULL);\r
+\r
+  iph = (struct iphdr*) ipPacket;\r
+\r
+  iph->ttl--; /* decrement ttl */\r
+  sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */\r
+  iph->check = htons(sum + (sum>>16)); /* add carry */\r
+} /* DecreaseTtlAndUpdateHeaderChecksum */\r
+\r
+\r
+\r
+\r
+/*\r
+ * Local Variables:\r
+ * c-basic-offset: 2\r
+ * indent-tabs-mode: nil\r
+ * End:\r
+ */\r
index bc97111..4c3ad58 100644 (file)
@@ -1,73 +1,85 @@
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-
-#ifndef _P2PD_PACKET_H
-#define _P2PD_PACKET_H
-
-/* System includes */
-#include <netinet/ip.h>         /* struct ip */
-#include <netinet/ip6.h>         /* struct ip6_hdr */
-#include <net/if.h>             /* IFNAMSIZ, IFHWADDRLEN */
-#include <sys/types.h>          /* u_int8_t, u_int16_t */
-
-/* P2PD-encapsulated packets are Ethernet-IP-UDP packets, which start
- * with a 8-bytes header (struct TEncapHeader), followed by the
- * encapsulated Ethernet-IP packet itself */
-
-struct TEncapHeader {
-  /* Use a standard Type-Length-Value (TLV) element */
-  u_int8_t type;
-  u_int8_t len;
-  u_int16_t reserved;                  /* Always 0 */
-  u_int32_t crc32;
-} __attribute__ ((__packed__));
-
-#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))
-
-int IsIpv4Fragment(struct ip*);
-int IsMulticastv4(struct ip*);
-int IsBroadcast(struct ip*);
-int IsIpv6Fragment(struct ip6_hdr*);
-int IsMulticastv6(struct ip6_hdr*);
-unsigned int GetIpHeaderLength(unsigned char *ipPacket);
-unsigned char *GetIpPacket(unsigned char *encapsulationUdpData);
-
-#endif /* _P2PD_PACKET_H */
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _P2PD_PACKET_H\r
+#define _P2PD_PACKET_H\r
+\r
+/* System includes */\r
+#include <netinet/ip.h>         /* struct ip */\r
+#include <netinet/ip6.h>         /* struct ip6_hdr */\r
+#include <net/if.h>             /* IFNAMSIZ, IFHWADDRLEN */\r
+#include <sys/types.h>          /* u_int8_t, u_int16_t */\r
+\r
+struct TSaveTtl\r
+{\r
+  u_int8_t ttl;\r
+  u_int16_t check;\r
+} __attribute__((__packed__));\r
+\r
+/* P2PD-encapsulated packets are Ethernet-IP-UDP packets, which start\r
+ * with a 8-bytes header (struct TEncapHeader), followed by the\r
+ * encapsulated Ethernet-IP packet itself */\r
+\r
+struct TEncapHeader {\r
+  /* Use a standard Type-Length-Value (TLV) element */\r
+  u_int8_t type;\r
+  u_int8_t len;\r
+  u_int16_t reserved;                  /* Always 0 */\r
+  u_int32_t crc32;\r
+} __attribute__ ((__packed__));\r
+\r
+#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))\r
+\r
+int IsIpFragment(unsigned char* ipPacket);\r
+u_int16_t GetIpTotalLength(unsigned char* ipPacket);\r
+int IsIpv4Fragment(struct ip*);\r
+int IsMulticastv4(struct ip*);\r
+int IsBroadcast(struct ip*);\r
+int IsIpv6Fragment(struct ip6_hdr*);\r
+int IsMulticastv6(struct ip6_hdr*);\r
+u_int8_t GetTtl(unsigned char* ipPacket);\r
+void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);\r
+void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);\r
+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket);\r
+unsigned int GetIpHeaderLength(unsigned char *ipPacket);\r
+unsigned char *GetIpPacket(unsigned char *encapsulationUdpData);\r
+\r
+#endif /* _P2PD_PACKET_H */\r
diff --git a/lib/p2pd/src/PacketHistory.c b/lib/p2pd/src/PacketHistory.c
new file mode 100644 (file)
index 0000000..18f1269
--- /dev/null
@@ -0,0 +1,316 @@
+/*\r
+ * OLSR Basic Multicast Forwarding (BMF) plugin.\r
+ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.\r
+ * Written by Erik Tromp.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without \r
+ * modification, are permitted provided that the following conditions \r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright \r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright \r
+ *   notice, this list of conditions and the following disclaimer in \r
+ *   the documentation and/or other materials provided with the \r
+ *   distribution.\r
+ * * Neither the name of Thales, BMF nor the names of its \r
+ *   contributors may be used to endorse or promote products derived \r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \r
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \r
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED \r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * File       : PacketHistory.c\r
+ * Description: Functions for keeping and accessing the history of processed\r
+ *              multicast IP packets.\r
+ * Created    : 29 Jun 2006\r
+ *\r
+ * ------------------------------------------------------------------------- */\r
+\r
+#include "PacketHistory.h"\r
+\r
+/* System includes */\r
+#include <stddef.h> /* NULL */\r
+#include <assert.h> /* assert() */\r
+#include <string.h> /* memset */\r
+#include <sys/types.h> /* u_int16_t, u_int32_t */\r
+#include <netinet/ip.h> /* struct iphdr */\r
+#include <stdlib.h> /* free() */\r
+\r
+/* OLSRD includes */\r
+#include "olsr.h" /* olsr_printf */\r
+#include "scheduler.h" /* GET_TIMESTAMP, TIMED_OUT */\r
+\r
+/* Plugin includes */\r
+#include "Packet.h"\r
+\r
+static struct TDupEntry* PacketHistory[HISTORY_HASH_SIZE];\r
+\r
+#define CRC_UPTO_NBYTES 256\r
+\r
+#if 0\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CalcCrcCcitt\r
+ * Description: Calculate 16-bits CRC according to CRC-CCITT specification\r
+ * Input      : buffer - the bytes to calculate the CRC value over\r
+ *              len - the number of bytes to calculate the CRC value over\r
+ * Output     : none\r
+ * Return     : CRC-16 value\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)\r
+{\r
+  /* Initial value of 0xFFFF should be 0x1D0F according to\r
+   * www.joegeluso.com/software/articles/ccitt.htm */\r
+  u_int16_t crc = 0xFFFF; \r
+  int i;\r
+\r
+  assert(buffer != NULL);\r
+\r
+  for (i = 0; i < len; i++)\r
+  {\r
+    crc  = (unsigned char)(crc >> 8) | (crc << 8);\r
+    crc ^= buffer[i];\r
+    crc ^= (unsigned char)(crc & 0xff) >> 4;\r
+    crc ^= (crc << 8) << 4;\r
+    crc ^= ((crc & 0xff) << 4) << 1;\r
+  }\r
+  return crc;\r
+} /* CalcCrcCcitt */\r
+#endif\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : GenerateCrc32Table\r
+ * Description: Generate the table of CRC remainders for all possible bytes,\r
+ *              according to CRC-32-IEEE 802.3\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */\r
+\r
+static unsigned long CrcTable[256];\r
+\r
+static void GenerateCrc32Table(void)\r
+{\r
+  int i, j;\r
+  u_int32_t crc;\r
+  for (i = 0; i < 256; i++)\r
+  {\r
+    crc = (u_int32_t) i;\r
+    for (j = 0; j < 8; j++)\r
+    {\r
+      if (crc & 1)\r
+      {\r
+        crc = (crc >> 1) ^ CRC32_POLYNOMIAL;\r
+      }\r
+      else\r
+      {\r
+        crc = (crc >> 1);\r
+      }\r
+    }\r
+    CrcTable[i] = crc;\r
+  } /* for */\r
+} /* GenerateCrc32Table */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CalcCrc32\r
+ * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3\r
+ * Input      : buffer - the bytes to calculate the CRC value over\r
+ *              len - the number of bytes to calculate the CRC value over\r
+ * Output     : none\r
+ * Return     : CRC-32 value\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)\r
+{\r
+  int i, j;\r
+  u_int32_t crc = 0xffffffffUL;\r
+  for (i = 0; i < len; i++)\r
+  {\r
+    j = ((int) (crc & 0xFF) ^ *buffer++);\r
+    crc = (crc >> 8) ^ CrcTable[j];\r
+  }\r
+  return crc ^ 0xffffffffUL;\r
+} /* CalcCrc32 */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : PacketCrc32\r
+ * Description: Calculates the CRC-32 value for an IP packet\r
+ * Input      : ipPacket - the IP packet\r
+ *              len - the number of octets in the IP packet\r
+ * Output     : none\r
+ * Return     : 32-bits CRC value\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+u_int32_t PacketCrc32(unsigned char* ipPacket, ssize_t len)\r
+{\r
+  struct TSaveTtl sttl;\r
+  struct ip* ipHeader;\r
+  u_int32_t result;\r
+\r
+  assert(ipPacket != NULL);\r
+\r
+  /* Skip TTL: in a multi-homed OLSR-network, the same multicast packet\r
+   * may enter the network multiple times, each copy differing only in its\r
+   * TTL value. BMF must not calculate a different CRC for packets that\r
+   * differ only in TTL. Skip also the IP-header checksum, because it changes\r
+   * along with TTL. Besides, it is not a good idea to calculate a CRC over\r
+   * data that already contains a checksum.\r
+   *\r
+   * Clip number of bytes over which CRC is calculated to prevent\r
+   * long packets from possibly claiming too much CPU resources. */\r
+  assert(len > 0);\r
+  if (len > CRC_UPTO_NBYTES)\r
+  {\r
+    len = CRC_UPTO_NBYTES;\r
+  }\r
+\r
+  SaveTtlAndChecksum(ipPacket, &sttl);\r
+\r
+  ipHeader = (struct ip*)ipPacket;\r
+  ipHeader->ip_ttl = 0xFF; /* fixed value of TTL for CRC-32 calculation */\r
+  ipHeader->ip_sum = 0x5A5A; /* fixed value of IP header checksum for CRC-32 calculation */\r
+\r
+  result = CalcCrc32(ipPacket, len);\r
+\r
+  RestoreTtlAndChecksum(ipPacket, &sttl);\r
+  return result;\r
+} /* PacketCrc32 */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : Hash\r
+ * Description: Calculates a hash value from a 32-bit value\r
+ * Input      : from32 - 32-bit value\r
+ * Output     : none\r
+ * Return     : hash value\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+u_int32_t Hash(u_int32_t from32)\r
+{\r
+  return ((from32 >> N_HASH_BITS) + from32) & ((1 << N_HASH_BITS) - 1);\r
+} /* Hash */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : InitPacketHistory\r
+ * Description: Initialize the packet history table and CRC-32 table\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : PacketHistory\r
+ * ------------------------------------------------------------------------- */\r
+void InitPacketHistory(void)\r
+{\r
+  int i;\r
+\r
+  GenerateCrc32Table();\r
+\r
+  for(i = 0; i < HISTORY_HASH_SIZE; i++)\r
+  {\r
+    PacketHistory[i] = NULL;\r
+  }\r
+} /* InitPacketHistory */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CheckAndMarkRecentPacket\r
+ * Description: Check if this packet was seen recently, then record the fact\r
+ *              that this packet was seen recently.\r
+ * Input      : crc32 - 32-bits crc value of the packet\r
+ * Output     : none\r
+ * Return     : not recently seen (0), recently seen (1)\r
+ * Data Used  : PacketHistory\r
+ * ------------------------------------------------------------------------- */\r
+int CheckAndMarkRecentPacket(u_int32_t crc32)\r
+{\r
+  u_int32_t idx;\r
+  struct TDupEntry* walker;\r
+  struct TDupEntry* newEntry;\r
+\r
+  idx = Hash(crc32);\r
+  assert(idx < HISTORY_HASH_SIZE);\r
+\r
+  for (walker = PacketHistory[idx]; walker != NULL; walker = walker->next)\r
+  {\r
+    if (walker->crc32 == crc32)\r
+    {\r
+      /* Found duplicate entry */\r
+\r
+      /* Always mark as "seen recently": refresh time-out */\r
+      walker->timeOut = olsr_getTimestamp(HISTORY_HOLD_TIME);\r
+\r
+      return 1;\r
+    } /* if */\r
+  } /* for */\r
+\r
+  /* No duplicate entry found: create one */\r
+  newEntry = olsr_malloc(sizeof(struct TDupEntry), "BMF: TDupEntry");\r
+  if (newEntry != NULL)\r
+  {\r
+    newEntry->crc32 = crc32;\r
+    newEntry->timeOut = olsr_getTimestamp(HISTORY_HOLD_TIME);\r
+\r
+    /* Add new entry at the front of the list */\r
+    newEntry->next = PacketHistory[idx];\r
+    PacketHistory[idx] = newEntry;\r
+  }\r
+\r
+  return 0;\r
+} /* CheckAndMarkRecentPacket */\r
+  \r
+/* -------------------------------------------------------------------------\r
+ * Function   : PrunePacketHistory\r
+ * Description: Prune the packet history table.\r
+ * Input      : useless - not used\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : PacketHistory\r
+ * ------------------------------------------------------------------------- */\r
+void PrunePacketHistory(void* useless __attribute__ ((unused)))\r
+{\r
+  uint i;\r
+  for (i = 0; i < HISTORY_HASH_SIZE; i++)\r
+  {\r
+    if (PacketHistory[i] != NULL)\r
+    {\r
+      struct TDupEntry* nextEntry = PacketHistory[i];\r
+      struct TDupEntry* prevEntry = NULL;\r
+      while (nextEntry != NULL) \r
+      {\r
+        struct TDupEntry* entry = nextEntry;\r
+        nextEntry = entry->next;\r
+\r
+        if (olsr_isTimedOut(entry->timeOut))\r
+        {\r
+          /* De-queue */\r
+          if (prevEntry != NULL)\r
+          {\r
+            prevEntry->next = entry->next;\r
+          }\r
+          else\r
+          {\r
+            PacketHistory[i] = entry->next;\r
+          } /* if */\r
+\r
+          /* De-allocate memory */\r
+          free(entry); \r
+             }\r
+             else\r
+             {\r
+               prevEntry = entry;\r
+             } /* if */\r
+      } /* while */\r
+    } /* if (PacketHistory[i] != NULL) */\r
+  } /* for (i = ...) */\r
+} /* PrunePacketHistory */\r
diff --git a/lib/p2pd/src/PacketHistory.h b/lib/p2pd/src/PacketHistory.h
new file mode 100644 (file)
index 0000000..32cf3a7
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef _BMF_PACKETHISTORY_H\r
+#define _BMF_PACKETHISTORY_H\r
+\r
+/*\r
+ * OLSR Basic Multicast Forwarding (BMF) plugin.\r
+ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.\r
+ * Written by Erik Tromp.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without \r
+ * modification, are permitted provided that the following conditions \r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright \r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright \r
+ *   notice, this list of conditions and the following disclaimer in \r
+ *   the documentation and/or other materials provided with the \r
+ *   distribution.\r
+ * * Neither the name of Thales, BMF nor the names of its \r
+ *   contributors may be used to endorse or promote products derived \r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \r
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \r
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED \r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * File       : PacketHistory.h\r
+ * Description: Functions for keeping and accessing the history of processed\r
+ *              multicast IP packets.\r
+ * Created    : 29 Jun 2006\r
+ *\r
+ * ------------------------------------------------------------------------- */\r
+\r
+/* System includes */\r
+#include <sys/types.h> /* ssize_t */\r
+#include <sys/times.h> /* clock_t */\r
+\r
+#define N_HASH_BITS 15\r
+#define HISTORY_HASH_SIZE (1 << N_HASH_BITS)\r
+\r
+/* Time-out of duplicate entries, in milliseconds */\r
+#define HISTORY_HOLD_TIME 3000\r
+\r
+struct TDupEntry\r
+{\r
+  u_int32_t crc32;\r
+  clock_t timeOut;\r
+  struct TDupEntry* next;\r
+};\r
+\r
+void InitPacketHistory(void);\r
+u_int32_t PacketCrc32(unsigned char* ipPkt, ssize_t len);\r
+u_int32_t Hash(u_int32_t from32);\r
+void MarkRecentPacket(u_int32_t crc32);\r
+int CheckAndMarkRecentPacket(u_int32_t crc32);\r
+void PrunePacketHistory(void*);\r
+\r
+#endif /* _BMF_PACKETHISTORY_H */\r
index c133762..229081e 100644 (file)
@@ -1,98 +1,98 @@
-#include <stdlib.h>
-
-#include "olsr_types.h"
-#include "dllist.h"
-
-/*------------------------------------------------------------------------------
- * Description : appends a node to the list specified by the head and tail
- *               elements
- * Parameters  : head - pointer to the head of the list
- *               tail - pointer to the tail of the list
- *               data - pointer to the data to store in the list
- * Returns     : pointer to the newly created element in the list
- * Uses data   : none
- *------------------------------------------------------------------------------
- */
-struct node * append_node(struct node ** head, struct node ** tail, void * data)
-{
-  struct node * new = calloc(1, sizeof(struct node));
-
-  if (*head == NULL) {
-    *head = new;
-  } else {
-    new->prev = *tail;
-    (*tail)->next = new;
-  }
-
-  new->data = data;
-  *tail = new;
-
-  return new;
-}
-
-/*------------------------------------------------------------------------------
- * Description : removes the specified element from the list specified by the
- *               head and tail elements
- * Parameters  : head - pointer to the head of the list
- *               tail - pointer to the tail of the list
- *               node - the element to remove from the list
- *               free_data - indicator whether to free the content of the data
- *               element
- * Returns     : nothing
- * Uses data   : none
- *------------------------------------------------------------------------------
- */
-void remove_node(struct node ** head, struct node **tail, struct node * node, bool free_data)
-{
-  struct node * curr = NULL;
-
-  for (curr = *head; curr; curr = curr->next) {
-    if (curr == node) {
-      // Now we found the proper node so we can remove it
-
-      if (free_data)
-        free(curr->data);
-
-      if (curr == *head) {
-        // Head node
-        *head = curr->next;
-      } else if (curr == *tail) {
-        // Tail node
-        *tail = curr->prev;
-      } else {
-        // Middle node
-        curr->prev->next = curr->next;
-        curr->next->prev = curr->prev;
-      }
-
-      if (*head != NULL)
-        (*head)->prev = NULL;
-
-      if (*tail != NULL)
-        (*tail)->next = NULL;
-
-      if (curr != NULL) {
-        curr->next = curr->prev = NULL;
-        free(curr);
-      }
-      break; // Bail out if we handled a remove
-    }
-  }
-}
-
-/*------------------------------------------------------------------------------
- * Description : clears the entire list specified by the head and tail elements
- * Parameters  : head - pointer to the head of the list
- *               tail - pointer to the tail of the list
- *               free_data - indicator whether to free the data pointer
- * Returns     : nothing
- * Uses data   : none
- *------------------------------------------------------------------------------
- */
-void clear_list(struct node **head, struct node **tail, bool free_data)
-{
-  while (*head)
-    remove_node(head, tail, *head, free_data);
-}
-
-
+#include <stdlib.h>\r
+\r
+#include "olsr_types.h"\r
+#include "dllist.h"\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Description : appends a node to the list specified by the head and tail\r
+ *               elements\r
+ * Parameters  : head - pointer to the head of the list\r
+ *               tail - pointer to the tail of the list\r
+ *               data - pointer to the data to store in the list\r
+ * Returns     : pointer to the newly created element in the list\r
+ * Uses data   : none\r
+ *------------------------------------------------------------------------------\r
+ */\r
+struct node * append_node(struct node ** head, struct node ** tail, void * data)\r
+{\r
+  struct node * new = calloc(1, sizeof(struct node));\r
+\r
+  if (*head == NULL) {\r
+    *head = new;\r
+  } else {\r
+    new->prev = *tail;\r
+    (*tail)->next = new;\r
+  }\r
+\r
+  new->data = data;\r
+  *tail = new;\r
+\r
+  return new;\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Description : removes the specified element from the list specified by the\r
+ *               head and tail elements\r
+ * Parameters  : head - pointer to the head of the list\r
+ *               tail - pointer to the tail of the list\r
+ *               node - the element to remove from the list\r
+ *               free_data - indicator whether to free the content of the data\r
+ *               element\r
+ * Returns     : nothing\r
+ * Uses data   : none\r
+ *------------------------------------------------------------------------------\r
+ */\r
+void remove_node(struct node ** head, struct node **tail, struct node * node, bool free_data)\r
+{\r
+  struct node * curr = NULL;\r
+\r
+  for (curr = *head; curr; curr = curr->next) {\r
+    if (curr == node) {\r
+      // Now we found the proper node so we can remove it\r
+\r
+      if (free_data)\r
+        free(curr->data);\r
+\r
+      if (curr == *head) {\r
+        // Head node\r
+        *head = curr->next;\r
+      } else if (curr == *tail) {\r
+        // Tail node\r
+        *tail = curr->prev;\r
+      } else {\r
+        // Middle node\r
+        curr->prev->next = curr->next;\r
+        curr->next->prev = curr->prev;\r
+      }\r
+\r
+      if (*head != NULL)\r
+        (*head)->prev = NULL;\r
+\r
+      if (*tail != NULL)\r
+        (*tail)->next = NULL;\r
+\r
+      if (curr != NULL) {\r
+        curr->next = curr->prev = NULL;\r
+        free(curr);\r
+      }\r
+      break; // Bail out if we handled a remove\r
+    }\r
+  }\r
+}\r
+\r
+/*------------------------------------------------------------------------------\r
+ * Description : clears the entire list specified by the head and tail elements\r
+ * Parameters  : head - pointer to the head of the list\r
+ *               tail - pointer to the tail of the list\r
+ *               free_data - indicator whether to free the data pointer\r
+ * Returns     : nothing\r
+ * Uses data   : none\r
+ *------------------------------------------------------------------------------\r
+ */\r
+void clear_list(struct node **head, struct node **tail, bool free_data)\r
+{\r
+  while (*head)\r
+    remove_node(head, tail, *head, free_data);\r
+}\r
+\r
+\r
index 64a867d..4be4cc2 100644 (file)
@@ -1,22 +1,22 @@
-/* 
- * File:   dllist.h
- * Author: Caspar
- *
- * Created on February 28, 2010, 1:59 PM
- */
-
-#ifndef _DLLIST_H
-#define        _DLLIST_H
-
-struct node {
-  void * data;
-  struct node * next;
-  struct node * prev;
-};
-
-struct node * append_node(struct node ** head, struct node ** tail, void * data);
-void remove_node(struct node ** head, struct node **tail, struct node * node, bool free_data);
-void clear_list(struct node **head, struct node **tail, bool free_data);
-
-#endif /* _DLLIST_H */
-
+/* \r
+ * File:   dllist.h\r
+ * Author: Caspar\r
+ *\r
+ * Created on February 28, 2010, 1:59 PM\r
+ */\r
+\r
+#ifndef _DLLIST_H\r
+#define        _DLLIST_H\r
+\r
+struct node {\r
+  void * data;\r
+  struct node * next;\r
+  struct node * prev;\r
+};\r
+\r
+struct node * append_node(struct node ** head, struct node ** tail, void * data);\r
+void remove_node(struct node ** head, struct node **tail, struct node * node, bool free_data);\r
+void clear_list(struct node **head, struct node **tail, bool free_data);\r
+\r
+#endif /* _DLLIST_H */\r
+\r
index 7900d34..fd1ac25 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-/* System includes */
-#include <assert.h>             /* assert() */
-#include <stddef.h>             /* NULL */
-
-/* OLSRD includes */
-#include "olsrd_plugin.h"
-#include "plugin_util.h"
-#include "defs.h"               /* uint8_t, olsr_cnf */
-#include "scheduler.h"          /* olsr_start_timer() */
-#include "olsr_cfg.h"           /* olsr_cnf() */
-#include "olsr_cookie.h"        /* olsr_alloc_cookie() */
-
-/* P2PD includes */
-#include "p2pd.h"               /* InitP2pd(), CloseP2pd() */
-#include "NetworkInterfaces.h" /* AddNonOlsrIf */
-
-static void __attribute__ ((constructor)) my_init(void);
-static void __attribute__ ((destructor)) my_fini(void);
-
-//static struct olsr_cookie_info *prune_packet_history_timer_cookie;
-
-void olsr_plugin_exit(void);
-
-/* -------------------------------------------------------------------------
- * Function   : olsrd_plugin_interface_version
- * Description: Plugin interface version
- * Input      : none
- * Output     : none
- * Return     : P2PD plugin interface version number
- * Data Used  : none
- * Notes      : Called by main OLSRD (olsr_load_dl) to check plugin interface
- *              version
- * ------------------------------------------------------------------------- */
-int
-olsrd_plugin_interface_version(void)
-{
-  return PLUGIN_INTERFACE_VERSION;
-}
-
-/* -------------------------------------------------------------------------
- * Function   : olsrd_plugin_init
- * Description: Plugin initialisation
- * Input      : none
- * Output     : none
- * Return     : fail (0) or success (1)
- * Data Used  : olsr_cnf
- * Notes      : Called by main OLSRD (init_olsr_plugin) to initialize plugin
- * ------------------------------------------------------------------------- */
-int
-olsrd_plugin_init(void)
-{
-  return InitP2pd(NULL);
-}
-
-/* -------------------------------------------------------------------------
- * Function   : olsr_plugin_exit
- * Description: Plugin cleanup
- * Input      : none
- * Output     : none
- * Return     : none
- * Data Used  : none
- * Notes      : Called by my_fini() at unload of shared object
- * ------------------------------------------------------------------------- */
-void
-olsr_plugin_exit(void)
-{
-  CloseP2pd();
-}
-
-static const struct olsrd_plugin_parameters plugin_parameters[] = {
-  {.name = "NonOlsrIf",.set_plugin_parameter = &AddNonOlsrIf,.data = NULL},
-  {.name = "P2pdTtl", .set_plugin_parameter = &SetP2pdTtl, .data = NULL },
-  {.name = "UdpDestPort",.set_plugin_parameter = &AddUdpDestPort,.data = NULL},
-};
-
-/* -------------------------------------------------------------------------
- * Function   : olsrd_get_plugin_parameters
- * Description: Return the parameter table and its size
- * Input      : none
- * Output     : params - the parameter table
- *              size - its size in no. of entries
- * Return     : none
- * Data Used  : plugin_parameters
- * Notes      : Called by main OLSR (init_olsr_plugin) for all plugins
- * ------------------------------------------------------------------------- */
-void
-olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
-{
-  *params = plugin_parameters;
-  *size = ARRAYSIZE(plugin_parameters);
-}
-
-/* -------------------------------------------------------------------------
- * Function   : my_init
- * Description: Plugin constructor
- * Input      : none
- * Output     : none
- * Return     : none
- * Data Used  : none
- * Notes      : Called at load of shared object
- * ------------------------------------------------------------------------- */
-static void
-my_init(void)
-{
-  /* Print plugin info to stdout */
-  printf("%s\n", MOD_DESC);
-
-  return;
-}
-
-/* -------------------------------------------------------------------------
- * Function   : my_fini
- * Description: Plugin destructor
- * Input      : none
- * Output     : none
- * Return     : none
- * Data Used  : none
- * Notes      : Called at unload of shared object
- * ------------------------------------------------------------------------- */
-static void
-my_fini(void)
-{
-  olsr_plugin_exit();
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+/* System includes */\r
+#include <assert.h>             /* assert() */\r
+#include <stddef.h>             /* NULL */\r
+\r
+/* OLSRD includes */\r
+#include "olsrd_plugin.h"\r
+#include "plugin_util.h"\r
+#include "defs.h"               /* uint8_t, olsr_cnf */\r
+#include "scheduler.h"          /* olsr_start_timer() */\r
+#include "olsr_cfg.h"           /* olsr_cnf() */\r
+#include "olsr_cookie.h"        /* olsr_alloc_cookie() */\r
+\r
+/* P2PD includes */\r
+#include "p2pd.h"               /* InitP2pd(), CloseP2pd() */\r
+#include "NetworkInterfaces.h" /* AddNonOlsrIf */\r
+\r
+static void __attribute__ ((constructor)) my_init(void);\r
+static void __attribute__ ((destructor)) my_fini(void);\r
+\r
+//static struct olsr_cookie_info *prune_packet_history_timer_cookie;\r
+\r
+void olsr_plugin_exit(void);\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : olsrd_plugin_interface_version\r
+ * Description: Plugin interface version\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : P2PD plugin interface version number\r
+ * Data Used  : none\r
+ * Notes      : Called by main OLSRD (olsr_load_dl) to check plugin interface\r
+ *              version\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+olsrd_plugin_interface_version(void)\r
+{\r
+  return PLUGIN_INTERFACE_VERSION;\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : olsrd_plugin_init\r
+ * Description: Plugin initialisation\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : fail (0) or success (1)\r
+ * Data Used  : olsr_cnf\r
+ * Notes      : Called by main OLSRD (init_olsr_plugin) to initialize plugin\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+olsrd_plugin_init(void)\r
+{\r
+  return InitP2pd(NULL);\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : olsr_plugin_exit\r
+ * Description: Plugin cleanup\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * Notes      : Called by my_fini() at unload of shared object\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+olsr_plugin_exit(void)\r
+{\r
+  CloseP2pd();\r
+}\r
+\r
+static const struct olsrd_plugin_parameters plugin_parameters[] = {\r
+  {.name = "NonOlsrIf",.set_plugin_parameter = &AddNonOlsrIf,.data = NULL},\r
+  {.name = "P2pdTtl", .set_plugin_parameter = &SetP2pdTtl, .data = NULL },\r
+  {.name = "UdpDestPort",.set_plugin_parameter = &AddUdpDestPort,.data = NULL},\r
+};\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : olsrd_get_plugin_parameters\r
+ * Description: Return the parameter table and its size\r
+ * Input      : none\r
+ * Output     : params - the parameter table\r
+ *              size - its size in no. of entries\r
+ * Return     : none\r
+ * Data Used  : plugin_parameters\r
+ * Notes      : Called by main OLSR (init_olsr_plugin) for all plugins\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)\r
+{\r
+  *params = plugin_parameters;\r
+  *size = ARRAYSIZE(plugin_parameters);\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : my_init\r
+ * Description: Plugin constructor\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * Notes      : Called at load of shared object\r
+ * ------------------------------------------------------------------------- */\r
+static void\r
+my_init(void)\r
+{\r
+  /* Print plugin info to stdout */\r
+  printf("%s\n", MOD_DESC);\r
+\r
+  return;\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : my_fini\r
+ * Description: Plugin destructor\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * Notes      : Called at unload of shared object\r
+ * ------------------------------------------------------------------------- */\r
+static void\r
+my_fini(void)\r
+{\r
+  olsr_plugin_exit();\r
+}\r
+\r
+/*\r
+ * Local Variables:\r
+ * c-basic-offset: 2\r
+ * indent-tabs-mode: nil\r
+ * End:\r
+ */\r
index 1e40b0d..3a9fdf7 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-
-#include "p2pd.h"
-
-/* System includes */
-#include <stddef.h>             /* NULL */
-#include <sys/types.h>          /* ssize_t */
-#include <string.h>             /* strerror() */
-#include <stdarg.h>             /* va_list, va_start, va_end */
-#include <errno.h>              /* errno */
-#include <assert.h>             /* assert() */
-#include <unistd.h>
-#include <fcntl.h>
-#include <linux/if_ether.h>     /* ETH_P_IP */
-#include <linux/if_packet.h>    /* struct sockaddr_ll, PACKET_MULTICAST */
-//#include <pthread.h> /* pthread_t, pthread_create() */
-#include <signal.h>             /* sigset_t, sigfillset(), sigdelset(), SIGINT */
-#include <netinet/ip.h>         /* struct ip */
-#include <netinet/udp.h>        /* struct udphdr */
-#include <unistd.h>             /* close() */
-
-#include <netinet/in.h>
-#include <netinet/ip6.h>
-
-#include <time.h>
-
-/* OLSRD includes */
-#include "plugin_util.h"        /* set_plugin_int */
-#include "defs.h"               /* olsr_cnf, //OLSR_PRINTF */
-#include "ipcalc.h"
-#include "olsr.h"               /* //OLSR_PRINTF */
-#include "mid_set.h"            /* mid_lookup_main_addr() */
-#include "link_set.h"           /* get_best_link_to_neighbor() */
-#include "net_olsr.h"           /* ipequal */
-#include "log.h"                /* Teco: syslog */
-#include "parser.h"
-
-/* plugin includes */
-#include "NetworkInterfaces.h"  /* NonOlsrInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
-//#include "Address.h"            /* IsMulticast() */
-#include "Packet.h"             /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
-#include "dllist.h"
-
-int P2pdTtl=0;
-int P2pdDuplicateTimeout           = P2PD_VALID_TIME;
-
-/* List of UDP destination address and port information */
-struct UdpDestPort *                 UdpDestPortList = NULL;
-
-/* List of filter entries to check for duplicate messages
- */
-struct node *                        dupFilterHead = NULL;
-struct node *                        dupFilterTail = NULL;
-
-bool is_broadcast(const struct sockaddr_in addr);
-bool is_multicast(const struct sockaddr_in addr);
-
-/* -------------------------------------------------------------------------
- * Function   : PacketReceivedFromOLSR
- * Description: Handle a received packet from a OLSR message
- * Input      : ipPacket into an unsigned char and the lenght of the packet
- * Output     : none
- * Return     : none
- * Data Used  : BmfInterfaces
- * ------------------------------------------------------------------------- */
-static void
-PacketReceivedFromOLSR(unsigned char *encapsulationUdpData, int len)
-{
-  struct ip *ipHeader;        /* IP header inside the encapsulated IP packet */
-  struct ip6_hdr *ip6Header;  /* IP header inside the encapsulated IP packet */
-  struct NonOlsrInterface *walker;
-  int stripped_len = 0;
-  ipHeader = (struct ip *)encapsulationUdpData;
-  ip6Header = (struct ip6_hdr *)encapsulationUdpData;
-  //OLSR_DEBUG(LOG_PLUGINS, "P2PD PLUGIN got packet from OLSR message\n");
-
-  /* Check with each network interface what needs to be done on it */
-  for (walker = nonOlsrInterfaces; walker != NULL; walker = walker->next) {
-    /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
-    if (walker->olsrIntf == NULL) {
-      int nBytesWritten;
-      struct sockaddr_ll dest;
-
-      memset(&dest, 0, sizeof(dest));
-      dest.sll_family = AF_PACKET;
-      if ((encapsulationUdpData[0] & 0xf0) == 0x40) {
-        dest.sll_protocol = htons(ETH_P_IP);
-        stripped_len = ntohs(ipHeader->ip_len);
-      }
-      
-      if ((encapsulationUdpData[0] & 0xf0) == 0x60) {
-        dest.sll_protocol = htons(ETH_P_IPV6);
-        stripped_len = 40 + ntohs(ip6Header->ip6_plen); //IPv6 Header size (40) + payload_len 
-      }
-      
-      // Sven-Ola: Don't know how to handle the "stripped_len is uninitialized" condition, maybe exit(1) is better...?
-      if (0 == stripped_len)
-        return;
-      
-      //TODO: if packet is not IP die here
-      
-      if (stripped_len > len) {
-      }
-      
-      dest.sll_ifindex = if_nametoindex(walker->ifName);
-      dest.sll_halen = IFHWADDRLEN;
-
-      if (olsr_cnf->ip_version == AF_INET) {
-        /* Use all-ones as destination MAC address. When the IP destination is
-         * a multicast address, the destination MAC address should normally also
-         * be a multicast address. E.g., when the destination IP is 224.0.0.1,
-         * the destination MAC should be 01:00:5e:00:00:01. However, it does not
-         * seem to matter when the destination MAC address is set to all-ones
-         * in that case. */
-
-        if (IsMulticastv4(ipHeader)) {
-          dest.sll_addr[0] = 0x01;
-          dest.sll_addr[1] = 0x00;
-          dest.sll_addr[2] = 0x5E;
-          dest.sll_addr[3] = (ipHeader->ip_dst.s_addr >> 16) & 0xFF;
-          dest.sll_addr[4] = (ipHeader->ip_dst.s_addr >> 8) & 0xFF;
-          dest.sll_addr[5] = ipHeader->ip_dst.s_addr & 0xFF;
-        } else /* if (IsBroadcast(ipHeader)) */ {
-          memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
-        }
-      } else /*(olsr_cnf->ip_version == AF_INET6) */ {
-        if (IsMulticastv6(ip6Header)) {
-          dest.sll_addr[0] = 0x33;
-          dest.sll_addr[1] = 0x33;
-          dest.sll_addr[2] = ip6Header->ip6_dst.s6_addr[12];
-          dest.sll_addr[3] = ip6Header->ip6_dst.s6_addr[13];
-          dest.sll_addr[4] = ip6Header->ip6_dst.s6_addr[14];
-          dest.sll_addr[5] = ip6Header->ip6_dst.s6_addr[15];
-        }
-      }
-
-      nBytesWritten = sendto(walker->capturingSkfd,
-                             encapsulationUdpData,
-                             stripped_len,
-                             0,
-                             (struct sockaddr *)&dest,
-                             sizeof(dest));
-      if (nBytesWritten != stripped_len) {
-        P2pdPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
-      } else {
-
-        //OLSR_PRINTF(
-        //  2,
-        //  "%s: --> unpacked and forwarded on \"%s\"\n",
-        //  PLUGIN_NAME_SHORT,
-        //  walker->ifName);
-      }
-    }                           /* if (walker->olsrIntf == NULL) */
-  }
-}                               /* PacketReceivedFromOLSR */
-
-/* Highest-numbered open socket file descriptor. To be used as first
- * parameter in calls to select(...). */
-int HighestSkfd = -1;
-
-/* Set of socket file descriptors */
-fd_set InputSet;
-
-bool
-p2pd_message_seen(struct node **head, struct node **tail, union olsr_message *m)
-{
-  struct node * curr;
-  time_t now;
-
-  now = time(NULL);
-  
-  // Check whether any entries have aged
-  curr = *head;
-  while (curr) {
-    struct DupFilterEntry *filter;
-    struct node * next = curr->next; // Save the current pointer since curr may be destroyed
-    
-    filter = (struct DupFilterEntry*)curr->data;
-    
-    if ((filter->creationtime + P2pdDuplicateTimeout) < now)
-      remove_node(head, tail, curr, true);
-      
-    // Skip to the next element
-    curr = next;
-  }
-  
-  // Now check whether there are any duplicates
-  for (curr = *head; curr; curr = curr->next) {
-    struct DupFilterEntry *filter = (struct DupFilterEntry*)curr->data;
-    
-    if (olsr_cnf->ip_version == AF_INET) {
-      if (filter->address.v4.s_addr  == m->v4.originator &&
-          filter->msgtype            == m->v4.olsr_msgtype &&
-          filter->seqno              == m->v4.seqno) {
-          return true;
-      }
-    } else /* if (olsr_cnf->ip_version == AF_INET6) */ {
-      if (memcmp(filter->address.v6.s6_addr,
-                 m->v6.originator.s6_addr,
-                 sizeof(m->v6.originator.s6_addr)) == 0 &&
-          filter->msgtype            == m->v6.olsr_msgtype &&
-          filter->seqno              == m->v6.seqno) {
-          return true;
-      }
-    }
-  }
-  
-  return false;
-}
-
-void
-p2pd_store_message(struct node **head, struct node **tail, union olsr_message *m)
-{
-  time_t now;
-
-  // Store a message into the database
-  struct DupFilterEntry *new_dup = calloc(1, sizeof(struct DupFilterEntry));
-  if (new_dup == NULL) {
-    olsr_printf(1, "P2PD: Out of memory\n");
-    return;
-  }
-
-  now = time(NULL);
-  
-  new_dup->creationtime = now;
-  if (olsr_cnf->ip_version == AF_INET) {
-    new_dup->address.v4.s_addr = m->v4.originator;
-    new_dup->msgtype = m->v4.olsr_msgtype;
-    new_dup->seqno = m->v4.seqno;
-  } else /* if (olsr_cnf->ip_version == AF_INET6) */ {
-    memcpy(new_dup->address.v6.s6_addr,
-           m->v6.originator.s6_addr,
-           sizeof(m->v6.originator.s6_addr));
-    new_dup->msgtype = m->v6.olsr_msgtype;
-    new_dup->seqno = m->v6.seqno;
-  }
-  
-  // Add the element to the head of the list
-  append_node(head, tail, new_dup);
-}
-
-bool
-p2pd_is_duplicate_message(union olsr_message *msg)
-{
-  if(p2pd_message_seen(&dupFilterHead, &dupFilterTail, msg)) {
-    return true;
-  }
-
-  p2pd_store_message(&dupFilterHead, &dupFilterTail, msg);
-  
-  return false;
-}
-
-bool
-olsr_parser(union olsr_message *m, struct interface *in_if __attribute__ ((unused)), union olsr_ip_addr *ipaddr __attribute__ ((unused)))
-{
-  union olsr_ip_addr originator;
-  int size;
-  uint32_t vtime;
-
-  //OLSR_DEBUG(LOG_PLUGINS, "P2PD PLUGIN: Received msg in parser\n");
-  
-       /* Fetch the originator of the messsage */
-  if (olsr_cnf->ip_version == AF_INET) {
-    memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
-    vtime = me_to_reltime(m->v4.olsr_vtime);
-    size = ntohs(m->v4.olsr_msgsize);
-  } else {
-    memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
-    vtime = me_to_reltime(m->v6.olsr_vtime);
-    size = ntohs(m->v6.olsr_msgsize);
-  }
-
-  /* Check if message originated from this node.
-   *         If so - back off */
-  if (ipequal(&originator, &olsr_cnf->main_addr))
-    return false;          /* Don't forward either */
-
-  /* Check for duplicates for processing */
-  if (p2pd_is_duplicate_message(m))
-    return true;  /* Don't process but allow to be forwarded */
-
-  if (olsr_cnf->ip_version == AF_INET) {
-    PacketReceivedFromOLSR((unsigned char *)&m->v4.message, size - 12);
-  } else {
-    PacketReceivedFromOLSR((unsigned char *)&m->v6.message, size - 12 - 96);
-  }
-
-       return true;
-}
-
-//Sends a packet in the OLSR network
-void
-olsr_p2pd_gen(unsigned char *packet, int len)
-{
-  /* send buffer: huge */
-  char buffer[10240];
-  int aligned_size;
-  union olsr_message *message = (union olsr_message *)buffer;
-  struct interface *ifn;
-  
-  aligned_size=len;
-
-  if ((aligned_size % 4) != 0) {
-    aligned_size = (aligned_size - (aligned_size % 4)) + 4;
-  }
-
-  /* fill message */
-  if (olsr_cnf->ip_version == AF_INET) {
-    /* IPv4 */
-    message->v4.olsr_msgtype  = P2PD_MESSAGE_TYPE;
-    message->v4.olsr_vtime    = reltime_to_me(P2PD_VALID_TIME * MSEC_PER_SEC);
-    memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
-    message->v4.ttl           = P2pdTtl ? P2pdTtl : MAX_TTL;
-    message->v4.hopcnt        = 0;
-    message->v4.seqno         = htons(get_msg_seqno());
-    message->v4.olsr_msgsize  = htons(aligned_size + 12);
-    memset(&message->v4.message, 0, aligned_size);
-    memcpy(&message->v4.message, packet, len);
-    aligned_size = aligned_size + 12;
-  } else /* if (olsr_cnf->ip_version == AF_INET6) */ {
-    /* IPv6 */
-    message->v6.olsr_msgtype  = P2PD_MESSAGE_TYPE;
-    message->v6.olsr_vtime    = reltime_to_me(P2PD_VALID_TIME * MSEC_PER_SEC);
-    memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
-    message->v6.ttl           = P2pdTtl ? P2pdTtl : MAX_TTL;
-    message->v6.hopcnt        = 0;
-    message->v6.seqno         = htons(get_msg_seqno());
-    message->v6.olsr_msgsize  = htons(aligned_size + 12 + 96);
-    memset(&message->v6.message, 0, aligned_size);
-    memcpy(&message->v6.message, packet, len);
-    aligned_size = aligned_size + 12 + 96;
-  }
-
-  /* looping trough interfaces */
-  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
-    //OLSR_PRINTF(1, "P2PD PLUGIN: Generating packet - [%s]\n", ifn->int_name);
-
-    if (net_outbuffer_push(ifn, message, aligned_size) != aligned_size) {
-      /* send data and try again */
-      net_output(ifn);
-      if (net_outbuffer_push(ifn, message, aligned_size) != aligned_size) {
-        //OLSR_PRINTF(1, "P2PD PLUGIN: could not send on interface: %s\n", ifn->int_name);
-      }
-    }
-  }
-}
-
-/* -------------------------------------------------------------------------
- * Function   : P2pdPError
- * Description: Prints an error message at OLSR debug level 1.
- *              First the plug-in name is printed. Then (if format is not NULL
- *              and *format is not empty) the arguments are printed, followed
- *              by a colon and a blank. Then the message and a new-line.
- * Input      : format, arguments
- * Output     : none
- * Return     : none
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-void
-P2pdPError(const char *format, ...)
-{
-#define MAX_STR_DESC 255
-  char strDesc[MAX_STR_DESC];
-
-#if !defined REMOVE_LOG_DEBUG
-  char *stringErr = strerror(errno);
-#endif
-
-  /* Rely on short-circuit boolean evaluation */
-  if (format == NULL || *format == '\0') {
-    //OLSR_DEBUG(LOG_PLUGINS, "%s: %s\n", PLUGIN_NAME, stringErr);
-  } else {
-    va_list arglist;
-
-    va_start(arglist, format);
-    vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
-    va_end(arglist);
-
-    strDesc[MAX_STR_DESC - 1] = '\0';   /* Ensures null termination */
-    
-#if !defined REMOVE_LOG_DEBUG
-    OLSR_DEBUG(LOG_PLUGINS, "%s: %s\n", strDesc, stringErr);
-#endif
-  }
-}                               /* P2pdPError */
-
-/* -------------------------------------------------------------------------
- * Function   : MainAddressOf
- * Description: Lookup the main address of a node
- * Input      : ip - IP address of the node
- * Output     : none
- * Return     : The main IP address of the node
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-union olsr_ip_addr *
-MainAddressOf(union olsr_ip_addr *ip)
-{
-  union olsr_ip_addr *result;
-
-  /* TODO: mid_lookup_main_addr() is not thread-safe! */
-  result = mid_lookup_main_addr(ip);
-  if (result == NULL) {
-    result = ip;
-  }
-  return result;
-}                               /* MainAddressOf */
-
-
-/* -------------------------------------------------------------------------
- * Function   : InUdpDestPortList
- * Description: Check whether the specified address and port is in the list of
- *              configured UDP destination/port entries
- * Input      : ip_version  - IP version to use for this check
- *              addr        - address to check for in the list
- *              port        - port to check for in the list
- * Output     : none
- * Return     : true if destination/port combination was found, false otherwise
- * Data Used  : UdpDestPortList
- * ------------------------------------------------------------------------- */
-bool
-InUdpDestPortList(int ip_version, union olsr_ip_addr *addr, uint16_t port)
-{
-  struct UdpDestPort *walker;
-  
-  for (walker = UdpDestPortList; walker; walker = walker->next) {
-    if (walker->ip_version == ip_version) {
-      if (ip_version == AF_INET) {
-        if (addr->v4.s_addr == walker->address.v4.s_addr &&
-            walker->port == port)
-          return true;  // Found so we can stop here
-      } else /* ip_version == AF_INET6 */ {
-        if (memcmp(addr->v6.s6_addr,
-                   walker->address.v6.s6_addr,
-                   sizeof(addr->v6.s6_addr) == 0) &&
-            walker->port == port)
-          return true;  // Found so we can stop here
-      }
-    }
-  }
-  return false;
-}
-
-/* -------------------------------------------------------------------------
- * Function   : P2pdPacketCaptured
- * Description: Handle a captured IP packet
- * Input      : encapsulationUdpData - space for the encapsulation header, 
- *                                                     followed by the captured IP packet
- *                                                     nBytes - The number of bytes in the data packet 
- * Output     : none
- * Return     : none
- * Data Used  : P2pdInterfaces
- * Notes      : The IP packet is assumed to be captured on a socket of family
- *              PF_PACKET and type SOCK_DGRAM (cooked).
- * ------------------------------------------------------------------------- */
-static void
-P2pdPacketCaptured(unsigned char *encapsulationUdpData, int nBytes)
-{
-  union olsr_ip_addr src;      /* Source IP address in captured packet */
-  union olsr_ip_addr dst;      /* Destination IP address in captured packet */
-  union olsr_ip_addr *origIp;  /* Main OLSR address of source of captured packet */
-  struct ip *ipHeader;         /* The IP header inside the captured IP packet */
-  struct ip6_hdr *ipHeader6;   /* The IP header inside the captured IP packet */
-  struct udphdr *udpHeader;
-  u_int16_t destPort;
-
-  if ((encapsulationUdpData[0] & 0xf0) == 0x40) {       //IPV4
-
-    ipHeader = (struct ip *)encapsulationUdpData;
-
-    dst.v4 = ipHeader->ip_dst;
-
-    if (ipHeader->ip_p != SOL_UDP) {
-      /* Not UDP */
-      //OLSR_PRINTF(1,"NON UDP PACKET\n");
-      return;                   /* for */
-    }
-
-    // If we're dealing with a fragment we bail out here since there's no valid
-    // UDP header in this message
-    if (IsIpv4Fragment(ipHeader)) {
-      return;
-    }
-    
-    udpHeader = (struct udphdr *)(encapsulationUdpData +
-                                  GetIpHeaderLength(encapsulationUdpData));
-    destPort = ntohs(udpHeader->dest);
-    
-    if (!InUdpDestPortList(AF_INET, &dst, destPort))
-       return;
-  }                            //END IPV4
-  else if ((encapsulationUdpData[0] & 0xf0) == 0x60) {  //IPv6
-
-    ipHeader6 = (struct ip6_hdr *)encapsulationUdpData;
-    
-    memcpy(&dst.v6, &ipHeader6->ip6_dst, sizeof(struct in6_addr));
-    
-    if (ipHeader6->ip6_dst.s6_addr[0] == 0xff)  //Multicast
-    {
-      //Continue
-    } else {
-      return;                   //not multicast
-    }
-    if (ipHeader6->ip6_nxt != SOL_UDP) {
-      /* Not UDP */
-      //OLSR_PRINTF(1,"NON UDP PACKET\n");
-      return;                   /* for */
-    }
-    
-    // Check whether this is a IPv6 fragment
-    if (IsIpv6Fragment(ipHeader6)) {
-      return;
-    }
-    
-    udpHeader = (struct udphdr *)(encapsulationUdpData + 40);
-    destPort = ntohs(udpHeader->dest);
-
-    if (!InUdpDestPortList(AF_INET6, &dst, destPort))
-      return;
-  }                             //END IPV6
-  else {
-    return;                     //Is not IP packet
-  }
-
-  /* Lookup main address of source in the MID table of OLSR */
-  origIp = MainAddressOf(&src);
-
-  // send the packet to OLSR forward mechanism
-  olsr_p2pd_gen(encapsulationUdpData, nBytes);
-}                               /* P2pdPacketCaptured */
-
-
-/* -------------------------------------------------------------------------
- * Function   : DoP2pd
- * Description: This function is registered with the OLSR scheduler and called when something is captured
- * Input      : none
- * Output     : none
- * Return     : none
- * Data Used  :
- * ------------------------------------------------------------------------- */
-void
-DoP2pd(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
-{
-  unsigned char rxBuffer[P2PD_BUFFER_SIZE];
-  if (skfd >= 0) {
-    struct sockaddr_ll pktAddr;
-    socklen_t addrLen = sizeof(pktAddr);
-    int nBytes;
-    unsigned char *ipPacket;
-
-    /* Receive the captured Ethernet frame, leaving space for the BMF
-     * encapsulation header */
-    ipPacket = GetIpPacket(rxBuffer);
-    nBytes = recvfrom(skfd, ipPacket, P2PD_BUFFER_SIZE,  //TODO: understand how to change this
-                      0, (struct sockaddr *)&pktAddr, &addrLen);
-    if (nBytes < 0) {
-
-      return;                   /* for */
-    }
-
-    /* if (nBytes < 0) */
-    /* Check if the number of received bytes is large enough for an IP
-     * packet which contains at least a minimum-size IP header.
-     * Note: There is an apparent bug in the packet socket implementation in
-     * combination with VLAN interfaces. On a VLAN interface, the value returned
-     * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
-     * returned on a non-VLAN interface, for the same ethernet frame. */
-    if (nBytes < (int)sizeof(struct ip)) {
-      ////OLSR_PRINTF(
-      //              1,
-      //              "%s: captured frame too short (%d bytes) on \"%s\"\n",
-      //              PLUGIN_NAME,
-      //              nBytes,
-      //              walker->ifName);
-
-      return;                   /* for */
-    }
-
-    if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
-        pktAddr.sll_pkttype == PACKET_MULTICAST ||
-        pktAddr.sll_pkttype == PACKET_BROADCAST) {
-      /* A multicast or broadcast packet was captured */
-
-      P2pdPacketCaptured(ipPacket, nBytes);
-
-    }                           /* if (pktAddr.sll_pkttype == ...) */
-  }                             /* if (skfd >= 0 && (FD_ISSET...)) */
-}                               /* DoP2pd */
-
-/* -------------------------------------------------------------------------
- * Function   : InitP2pd
- * Description: Initialize the P2pd plugin
- * Input      : skipThisInterface - pointer to interface to skip
- * Output     : none
- * Return     : Always 0
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-int
-InitP2pd(struct interface *skipThisIntf)
-{
-  //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
-  //olsr_parser_add_function(&olsr_parser, PARSER_TYPE,1);
-  olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
-  
-  //Creates captures sockets and register them to the OLSR scheduler
-  CreateNonOlsrNetworkInterfaces(skipThisIntf);
-
-  return 0;
-}                               /* InitP2pd */
-
-/* -------------------------------------------------------------------------
- * Function   : CloseP2pd
- * Description: Close the P2pd plugin and clean up
- * Input      : none
- * Output     : none
- * Return     : none
- * Data Used  :
- * ------------------------------------------------------------------------- */
-void
-CloseP2pd(void)
-{
-  CloseNonOlsrNetworkInterfaces();
-}
-
-/* -------------------------------------------------------------------------
- * Function   : SetP2pdTtl
- * Description: Set the TTL for message from this plugin
- * Input      : value - parameter value to evaluate
- * Output     : none
- * Return     : Always 0
- * Data Used  : P2pdTtl
- * ------------------------------------------------------------------------- */
-int
-SetP2pdTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
-{
-  assert(value != NULL);
-  P2pdTtl = atoi(value);
-
-  return 0;
-}
-
-bool is_broadcast(const struct sockaddr_in addr)
-{
-  if (addr.sin_addr.s_addr == 0xFFFFFFFF)
-    return true;
-    
-  return false;
-}
-
-bool is_multicast(const struct sockaddr_in addr)
-{
-  if ((htonl(addr.sin_addr.s_addr) & 0xE0000000) == 0xE0000000)
-    return true;
-
-  return false;
-}
-
-/* -------------------------------------------------------------------------
- * Function   : AddUdpDestPort
- * Description: Set the UDP destination/port combination as an entry in the
- *              UdpDestPortList
- * Input      : value - parameter value to evaluate
- * Output     : none
- * Return     : -1 on error condition, 0 if all is ok
- * Data Used  : UdpDestPortList
- * ------------------------------------------------------------------------- */
-int
-AddUdpDestPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
-{
-  char destAddr[INET6_ADDRSTRLEN];
-  uint16_t destPort;
-  int num;
-  struct UdpDestPort *    new;
-  struct sockaddr_in      addr4;
-  struct sockaddr_in6     addr6;
-  int                     ip_version   = AF_INET;
-  int                     res;
-  
-  assert(value != NULL);
-  
-  // Retrieve the data from the argument string passed
-  memset(destAddr, 0, sizeof(destAddr));
-  num = sscanf(value, "%45s %hd", destAddr, &destPort);
-  if (num != 2) {
-    olsr_printf(1, "Invalid argument for \"UdpDestPort\"");
-    return -1;
-  }
-       
-  // Check whether we're dealing with an IPv4 or IPv6 address
-  // When the string contains a ':' we can assume we're dealing with IPv6
-  if (strchr(destAddr, (int)':')) {
-    ip_version = AF_INET6;
-  }
-
-  // Check whether the specified address was either IPv4 multicast,
-  // IPv4 broadcast or IPv6 multicast.
-
-  switch (ip_version) {
-  case AF_INET:
-    res = inet_pton(AF_INET, destAddr, &addr4.sin_addr);
-    if (!is_broadcast(addr4) && !is_multicast(addr4)) {
-      olsr_printf(1, "WARNING: IPv4 address must be multicast or broadcast... ");
-    }
-    break;
-  case AF_INET6:
-    res = inet_pton(AF_INET6, destAddr, &addr6.sin6_addr);
-    if (addr6.sin6_addr.s6_addr[0] != 0xFF) {
-      olsr_printf(1, "WARNING: IPv6 address must be multicast... ");
-      return -1;
-    }
-    break;
-  }
-  // Determine whether it is a valid IP address
-  if (res == 0) {
-    olsr_printf(1, "Invalid address specified for \"UdpDestPort\"");
-    return -1;
-  }
-       
-  // Create a new entry and link it into the chain
-  new = calloc(1, sizeof(struct UdpDestPort));
-  if (new == NULL) {
-    olsr_printf(1, "P2PD: Out of memory");
-    return -1;
-  }
-       
-  new->ip_version = ip_version;
-  switch (ip_version) {
-  case AF_INET:
-    new->address.v4.s_addr = addr4.sin_addr.s_addr;
-    break;
-  case AF_INET6:
-    memcpy(&new->address.v6.s6_addr, &addr6.sin6_addr.s6_addr, sizeof(sizeof(addr6.sin6_addr.s6_addr)));
-    break;
-  }
-  new->port = destPort;
-  new->next = UdpDestPortList;
-  UdpDestPortList = new;
-       
-  // And then we're done
-  return 0;
-}
-
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+\r
+#include "p2pd.h"\r
+\r
+/* System includes */\r
+#include <stddef.h>             /* NULL */\r
+#include <sys/types.h>          /* ssize_t */\r
+#include <string.h>             /* strerror() */\r
+#include <stdarg.h>             /* va_list, va_start, va_end */\r
+#include <errno.h>              /* errno */\r
+#include <assert.h>             /* assert() */\r
+#include <unistd.h>\r
+#include <fcntl.h>\r
+#include <linux/if_ether.h>     /* ETH_P_IP */\r
+#include <linux/if_packet.h>    /* struct sockaddr_ll, PACKET_MULTICAST */\r
+//#include <pthread.h> /* pthread_t, pthread_create() */\r
+#include <signal.h>             /* sigset_t, sigfillset(), sigdelset(), SIGINT */\r
+#include <netinet/ip.h>         /* struct ip */\r
+#include <netinet/udp.h>        /* struct udphdr */\r
+#include <unistd.h>             /* close() */\r
+\r
+#include <netinet/in.h>\r
+#include <netinet/ip6.h>\r
+\r
+#include <time.h>\r
+\r
+/* OLSRD includes */\r
+#include "plugin_util.h"        /* set_plugin_int */\r
+#include "defs.h"               /* olsr_cnf, //OLSR_PRINTF */\r
+#include "ipcalc.h"\r
+#include "olsr.h"               /* //OLSR_PRINTF */\r
+#include "mid_set.h"            /* mid_lookup_main_addr() */\r
+#include "link_set.h"           /* get_best_link_to_neighbor() */\r
+#include "net_olsr.h"           /* ipequal */\r
+#include "log.h"                /* Teco: syslog */\r
+#include "parser.h"\r
+\r
+/* plugin includes */\r
+#include "NetworkInterfaces.h"  /* NonOlsrInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */\r
+//#include "Address.h"          /* IsMulticast() */\r
+#include "Packet.h"             /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */\r
+#include "PacketHistory.h"\r
+#include "dllist.h"\r
+\r
+int P2pdTtl=0;\r
+int P2pdDuplicateTimeout           = P2PD_VALID_TIME;\r
+\r
+/* List of UDP destination address and port information */\r
+struct UdpDestPort *                 UdpDestPortList = NULL;\r
+\r
+/* List of filter entries to check for duplicate messages\r
+ */\r
+struct node *                        dupFilterHead = NULL;\r
+struct node *                        dupFilterTail = NULL;\r
+\r
+clockid_t clockid = CLOCK_MONOTONIC;\r
+\r
+bool is_broadcast(const struct sockaddr_in addr);\r
+bool is_multicast(const struct sockaddr_in addr);\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : PacketReceivedFromOLSR\r
+ * Description: Handle a received packet from a OLSR message\r
+ * Input      : ipPacket into an unsigned char and the lenght of the packet\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : BmfInterfaces\r
+ * ------------------------------------------------------------------------- */\r
+static void\r
+PacketReceivedFromOLSR(unsigned char *encapsulationUdpData, int len)\r
+{\r
+  struct ip *ipHeader;        /* IP header inside the encapsulated IP packet */\r
+  struct ip6_hdr *ip6Header;  /* IP header inside the encapsulated IP packet */\r
+  struct NonOlsrInterface *walker;\r
+  int stripped_len = 0;\r
+  unsigned char * ipPacket;\r
+  uint16_t ipPacketLen;\r
+  uint32_t crc32;\r
+  ipHeader = (struct ip *)encapsulationUdpData;\r
+  ip6Header = (struct ip6_hdr *)encapsulationUdpData;\r
+  //OLSR_DEBUG(LOG_PLUGINS, "P2PD PLUGIN got packet from OLSR message\n");\r
+\r
+  /* Check for duplicate IP packets now based on a hash */\r
+  ipPacket = GetIpPacket(encapsulationUdpData);\r
+  if (IsIpFragment(ipPacket))\r
+  {\r
+    return;\r
+  }\r
+  ipPacketLen = GetIpTotalLength(ipPacket);\r
+\r
+  /* Calculate packet fingerprint */\r
+  crc32 = PacketCrc32(ipPacket, ipPacketLen);\r
+\r
+  /* Check if this packet was seen recently */\r
+  if (CheckAndMarkRecentPacket(crc32))\r
+  {\r
+    OLSR_PRINTF(\r
+      8,\r
+      "%s: --> discarding: packet is duplicate\n",\r
+      PLUGIN_NAME_SHORT);\r
+    return;\r
+  }\r
+\r
+  PrunePacketHistory(NULL);\r
+\r
+  /* Check with each network interface what needs to be done on it */\r
+  for (walker = nonOlsrInterfaces; walker != NULL; walker = walker->next) {\r
+    /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */\r
+    if (walker->olsrIntf == NULL) {\r
+      int nBytesWritten;\r
+      struct sockaddr_ll dest;\r
+\r
+      memset(&dest, 0, sizeof(dest));\r
+      dest.sll_family = AF_PACKET;\r
+      if ((encapsulationUdpData[0] & 0xf0) == 0x40) {\r
+        dest.sll_protocol = htons(ETH_P_IP);\r
+        stripped_len = ntohs(ipHeader->ip_len);\r
+      }\r
+      \r
+      if ((encapsulationUdpData[0] & 0xf0) == 0x60) {\r
+        dest.sll_protocol = htons(ETH_P_IPV6);\r
+        stripped_len = 40 + ntohs(ip6Header->ip6_plen); //IPv6 Header size (40) + payload_len \r
+      }\r
+      \r
+      // Sven-Ola: Don't know how to handle the "stripped_len is uninitialized" condition, maybe exit(1) is better...?\r
+      if (0 == stripped_len)\r
+        return;\r
+      \r
+      //TODO: if packet is not IP die here\r
+      \r
+      if (stripped_len > len) {\r
+      }\r
+      \r
+      dest.sll_ifindex = if_nametoindex(walker->ifName);\r
+      dest.sll_halen = IFHWADDRLEN;\r
+\r
+      if (olsr_cnf->ip_version == AF_INET) {\r
+        /* Use all-ones as destination MAC address. When the IP destination is\r
+         * a multicast address, the destination MAC address should normally also\r
+         * be a multicast address. E.g., when the destination IP is 224.0.0.1,\r
+         * the destination MAC should be 01:00:5e:00:00:01. However, it does not\r
+         * seem to matter when the destination MAC address is set to all-ones\r
+         * in that case. */\r
+\r
+        if (IsMulticastv4(ipHeader)) {\r
+          dest.sll_addr[0] = 0x01;\r
+          dest.sll_addr[1] = 0x00;\r
+          dest.sll_addr[2] = 0x5E;\r
+          dest.sll_addr[3] = (ipHeader->ip_dst.s_addr >> 16) & 0x7F;\r
+          dest.sll_addr[4] = (ipHeader->ip_dst.s_addr >> 8) & 0xFF;\r
+          dest.sll_addr[5] = ipHeader->ip_dst.s_addr & 0xFF;\r
+        } else /* if (IsBroadcast(ipHeader)) */ {\r
+          memset(dest.sll_addr, 0xFF, IFHWADDRLEN);\r
+        }\r
+      } else /*(olsr_cnf->ip_version == AF_INET6) */ {\r
+        if (IsMulticastv6(ip6Header)) {\r
+          dest.sll_addr[0] = 0x33;\r
+          dest.sll_addr[1] = 0x33;\r
+          dest.sll_addr[2] = ip6Header->ip6_dst.s6_addr[12];\r
+          dest.sll_addr[3] = ip6Header->ip6_dst.s6_addr[13];\r
+          dest.sll_addr[4] = ip6Header->ip6_dst.s6_addr[14];\r
+          dest.sll_addr[5] = ip6Header->ip6_dst.s6_addr[15];\r
+        }\r
+      }\r
+\r
+      nBytesWritten = sendto(walker->capturingSkfd,\r
+                             encapsulationUdpData,\r
+                             stripped_len,\r
+                             0,\r
+                             (struct sockaddr *)&dest,\r
+                             sizeof(dest));\r
+      if (nBytesWritten != stripped_len) {\r
+        P2pdPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);\r
+      } else {\r
+\r
+        //OLSR_PRINTF(\r
+        //  2,\r
+        //  "%s: --> unpacked and forwarded on \"%s\"\n",\r
+        //  PLUGIN_NAME_SHORT,\r
+        //  walker->ifName);\r
+      }\r
+    }                           /* if (walker->olsrIntf == NULL) */\r
+  }\r
+}                               /* PacketReceivedFromOLSR */\r
+\r
+/* Highest-numbered open socket file descriptor. To be used as first\r
+ * parameter in calls to select(...). */\r
+int HighestSkfd = -1;\r
+\r
+/* Set of socket file descriptors */\r
+fd_set InputSet;\r
+\r
+bool\r
+p2pd_message_seen(struct node **head, struct node **tail, union olsr_message *m)\r
+{\r
+  struct node * curr;\r
+  time_t now;\r
+\r
+  now = time(NULL);\r
+  \r
+  // Check whether any entries have aged\r
+  curr = *head;\r
+  while (curr) {\r
+    struct DupFilterEntry *filter;\r
+    struct node * next = curr->next; // Save the current pointer since curr may be destroyed\r
+    \r
+    filter = (struct DupFilterEntry*)curr->data;\r
+    \r
+    if ((filter->creationtime + P2pdDuplicateTimeout) < now)\r
+      remove_node(head, tail, curr, true);\r
+      \r
+    // Skip to the next element\r
+    curr = next;\r
+  }\r
+  \r
+  // Now check whether there are any duplicates\r
+  for (curr = *head; curr; curr = curr->next) {\r
+    struct DupFilterEntry *filter = (struct DupFilterEntry*)curr->data;\r
+    \r
+    if (olsr_cnf->ip_version == AF_INET) {\r
+      if (filter->address.v4.s_addr  == m->v4.originator &&\r
+          filter->msgtype            == m->v4.olsr_msgtype &&\r
+          filter->seqno              == m->v4.seqno) {\r
+          return true;\r
+      }\r
+    } else /* if (olsr_cnf->ip_version == AF_INET6) */ {\r
+      if (memcmp(filter->address.v6.s6_addr,\r
+                 m->v6.originator.s6_addr,\r
+                 sizeof(m->v6.originator.s6_addr)) == 0 &&\r
+          filter->msgtype            == m->v6.olsr_msgtype &&\r
+          filter->seqno              == m->v6.seqno) {\r
+          return true;\r
+      }\r
+    }\r
+  }\r
+  \r
+  return false;\r
+}\r
+\r
+void\r
+p2pd_store_message(struct node **head, struct node **tail, union olsr_message *m)\r
+{\r
+  time_t now;\r
+\r
+  // Store a message into the database\r
+  struct DupFilterEntry *new_dup = calloc(1, sizeof(struct DupFilterEntry));\r
+  if (new_dup == NULL) {\r
+    olsr_printf(1, "P2PD: Out of memory\n");\r
+    return;\r
+  }\r
+\r
+  now = time(NULL);\r
+  \r
+  new_dup->creationtime = now;\r
+  if (olsr_cnf->ip_version == AF_INET) {\r
+    new_dup->address.v4.s_addr = m->v4.originator;\r
+    new_dup->msgtype = m->v4.olsr_msgtype;\r
+    new_dup->seqno = m->v4.seqno;\r
+  } else /* if (olsr_cnf->ip_version == AF_INET6) */ {\r
+    memcpy(new_dup->address.v6.s6_addr,\r
+           m->v6.originator.s6_addr,\r
+           sizeof(m->v6.originator.s6_addr));\r
+    new_dup->msgtype = m->v6.olsr_msgtype;\r
+    new_dup->seqno = m->v6.seqno;\r
+  }\r
+  \r
+  // Add the element to the head of the list\r
+  append_node(head, tail, new_dup);\r
+}\r
+\r
+bool\r
+p2pd_is_duplicate_message(union olsr_message *msg)\r
+{\r
+  if(p2pd_message_seen(&dupFilterHead, &dupFilterTail, msg)) {\r
+    return true;\r
+  }\r
+\r
+  p2pd_store_message(&dupFilterHead, &dupFilterTail, msg);\r
+  \r
+  return false;\r
+}\r
+\r
+bool\r
+olsr_parser(union olsr_message *m, struct interface *in_if __attribute__ ((unused)), union olsr_ip_addr *ipaddr __attribute__ ((unused)))\r
+{\r
+  union olsr_ip_addr originator;\r
+  int size;\r
+  uint32_t vtime;\r
+\r
+  //OLSR_DEBUG(LOG_PLUGINS, "P2PD PLUGIN: Received msg in parser\n");\r
+  \r
+       /* Fetch the originator of the messsage */\r
+  if (olsr_cnf->ip_version == AF_INET) {\r
+    memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);\r
+    vtime = me_to_reltime(m->v4.olsr_vtime);\r
+    size = ntohs(m->v4.olsr_msgsize);\r
+  } else {\r
+    memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);\r
+    vtime = me_to_reltime(m->v6.olsr_vtime);\r
+    size = ntohs(m->v6.olsr_msgsize);\r
+  }\r
+\r
+  /* Check if message originated from this node.\r
+   *         If so - back off */\r
+  if (ipequal(&originator, &olsr_cnf->main_addr))\r
+    return false;          /* Don't forward either */\r
+\r
+  /* Check for duplicate messages for processing */\r
+  if (p2pd_is_duplicate_message(m))\r
+    return true;  /* Don't process but allow to be forwarded */\r
+\r
+  if (olsr_cnf->ip_version == AF_INET) {\r
+    PacketReceivedFromOLSR((unsigned char *)&m->v4.message, size - 12);\r
+  } else {\r
+    PacketReceivedFromOLSR((unsigned char *)&m->v6.message, size - 12 - 96);\r
+  }\r
+\r
+       return true;\r
+}\r
+\r
+//Sends a packet in the OLSR network\r
+void\r
+olsr_p2pd_gen(unsigned char *packet, int len)\r
+{\r
+  /* send buffer: huge */\r
+  char buffer[10240];\r
+  int aligned_size;\r
+  union olsr_message *message = (union olsr_message *)buffer;\r
+  struct interface *ifn;\r
+  \r
+  aligned_size=len;\r
+\r
+  if ((aligned_size % 4) != 0) {\r
+    aligned_size = (aligned_size - (aligned_size % 4)) + 4;\r
+  }\r
+\r
+  /* fill message */\r
+  if (olsr_cnf->ip_version == AF_INET) {\r
+    /* IPv4 */\r
+    message->v4.olsr_msgtype  = P2PD_MESSAGE_TYPE;\r
+    message->v4.olsr_vtime    = reltime_to_me(P2PD_VALID_TIME * MSEC_PER_SEC);\r
+    memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);\r
+    message->v4.ttl           = P2pdTtl ? P2pdTtl : MAX_TTL;\r
+    message->v4.hopcnt        = 0;\r
+    message->v4.seqno         = htons(get_msg_seqno());\r
+    message->v4.olsr_msgsize  = htons(aligned_size + 12);\r
+    memset(&message->v4.message, 0, aligned_size);\r
+    memcpy(&message->v4.message, packet, len);\r
+    aligned_size = aligned_size + 12;\r
+  } else /* if (olsr_cnf->ip_version == AF_INET6) */ {\r
+    /* IPv6 */\r
+    message->v6.olsr_msgtype  = P2PD_MESSAGE_TYPE;\r
+    message->v6.olsr_vtime    = reltime_to_me(P2PD_VALID_TIME * MSEC_PER_SEC);\r
+    memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);\r
+    message->v6.ttl           = P2pdTtl ? P2pdTtl : MAX_TTL;\r
+    message->v6.hopcnt        = 0;\r
+    message->v6.seqno         = htons(get_msg_seqno());\r
+    message->v6.olsr_msgsize  = htons(aligned_size + 12 + 96);\r
+    memset(&message->v6.message, 0, aligned_size);\r
+    memcpy(&message->v6.message, packet, len);\r
+    aligned_size = aligned_size + 12 + 96;\r
+  }\r
+\r
+  /* looping trough interfaces */\r
+  for (ifn = ifnet; ifn; ifn = ifn->int_next) {\r
+    //OLSR_PRINTF(1, "P2PD PLUGIN: Generating packet - [%s]\n", ifn->int_name);\r
+\r
+    if (net_outbuffer_push(ifn, message, aligned_size) != aligned_size) {\r
+      /* send data and try again */\r
+      net_output(ifn);\r
+      if (net_outbuffer_push(ifn, message, aligned_size) != aligned_size) {\r
+        //OLSR_PRINTF(1, "P2PD PLUGIN: could not send on interface: %s\n", ifn->int_name);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : P2pdPError\r
+ * Description: Prints an error message at OLSR debug level 1.\r
+ *              First the plug-in name is printed. Then (if format is not NULL\r
+ *              and *format is not empty) the arguments are printed, followed\r
+ *              by a colon and a blank. Then the message and a new-line.\r
+ * Input      : format, arguments\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+P2pdPError(const char *format, ...)\r
+{\r
+#define MAX_STR_DESC 255\r
+  char strDesc[MAX_STR_DESC];\r
+\r
+#if !defined REMOVE_LOG_DEBUG\r
+  char *stringErr = strerror(errno);\r
+#endif\r
+\r
+  /* Rely on short-circuit boolean evaluation */\r
+  if (format == NULL || *format == '\0') {\r
+    //OLSR_DEBUG(LOG_PLUGINS, "%s: %s\n", PLUGIN_NAME, stringErr);\r
+  } else {\r
+    va_list arglist;\r
+\r
+    va_start(arglist, format);\r
+    vsnprintf(strDesc, MAX_STR_DESC, format, arglist);\r
+    va_end(arglist);\r
+\r
+    strDesc[MAX_STR_DESC - 1] = '\0';   /* Ensures null termination */\r
+    \r
+#if !defined REMOVE_LOG_DEBUG\r
+    OLSR_DEBUG(LOG_PLUGINS, "%s: %s\n", strDesc, stringErr);\r
+#endif\r
+  }\r
+}                               /* P2pdPError */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : MainAddressOf\r
+ * Description: Lookup the main address of a node\r
+ * Input      : ip - IP address of the node\r
+ * Output     : none\r
+ * Return     : The main IP address of the node\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+union olsr_ip_addr *\r
+MainAddressOf(union olsr_ip_addr *ip)\r
+{\r
+  union olsr_ip_addr *result;\r
+\r
+  /* TODO: mid_lookup_main_addr() is not thread-safe! */\r
+  result = mid_lookup_main_addr(ip);\r
+  if (result == NULL) {\r
+    result = ip;\r
+  }\r
+  return result;\r
+}                               /* MainAddressOf */\r
+\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : InUdpDestPortList\r
+ * Description: Check whether the specified address and port is in the list of\r
+ *              configured UDP destination/port entries\r
+ * Input      : ip_version  - IP version to use for this check\r
+ *              addr        - address to check for in the list\r
+ *              port        - port to check for in the list\r
+ * Output     : none\r
+ * Return     : true if destination/port combination was found, false otherwise\r
+ * Data Used  : UdpDestPortList\r
+ * ------------------------------------------------------------------------- */\r
+bool\r
+InUdpDestPortList(int ip_version, union olsr_ip_addr *addr, uint16_t port)\r
+{\r
+  struct UdpDestPort *walker;\r
+  \r
+  for (walker = UdpDestPortList; walker; walker = walker->next) {\r
+    if (walker->ip_version == ip_version) {\r
+      if (ip_version == AF_INET) {\r
+        if (addr->v4.s_addr == walker->address.v4.s_addr &&\r
+            walker->port == port)\r
+          return true;  // Found so we can stop here\r
+      } else /* ip_version == AF_INET6 */ {\r
+        if (memcmp(addr->v6.s6_addr,\r
+                   walker->address.v6.s6_addr,\r
+                   sizeof(addr->v6.s6_addr) == 0) &&\r
+            walker->port == port)\r
+          return true;  // Found so we can stop here\r
+      }\r
+    }\r
+  }\r
+  return false;\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : P2pdPacketCaptured\r
+ * Description: Handle a captured IP packet\r
+ * Input      : encapsulationUdpData - space for the encapsulation header, \r
+ *                                                     followed by the captured IP packet\r
+ *                                                     nBytes - The number of bytes in the data packet \r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  : P2pdInterfaces\r
+ * Notes      : The IP packet is assumed to be captured on a socket of family\r
+ *              PF_PACKET and type SOCK_DGRAM (cooked).\r
+ * ------------------------------------------------------------------------- */\r
+static void\r
+P2pdPacketCaptured(unsigned char *encapsulationUdpData, int nBytes)\r
+{\r
+  union olsr_ip_addr src;      /* Source IP address in captured packet */\r
+  union olsr_ip_addr dst;      /* Destination IP address in captured packet */\r
+  union olsr_ip_addr *origIp;  /* Main OLSR address of source of captured packet */\r
+  struct ip *ipHeader;         /* The IP header inside the captured IP packet */\r
+  struct ip6_hdr *ipHeader6;   /* The IP header inside the captured IP packet */\r
+  struct udphdr *udpHeader;\r
+  u_int16_t destPort;\r
+\r
+  if ((encapsulationUdpData[0] & 0xf0) == 0x40) {       //IPV4\r
+\r
+    ipHeader = (struct ip *)encapsulationUdpData;\r
+\r
+    dst.v4 = ipHeader->ip_dst;\r
+\r
+    if (ipHeader->ip_p != SOL_UDP) {\r
+      /* Not UDP */\r
+      //OLSR_PRINTF(1,"NON UDP PACKET\n");\r
+      return;                   /* for */\r
+    }\r
+\r
+    // If we're dealing with a fragment we bail out here since there's no valid\r
+    // UDP header in this message\r
+    if (IsIpv4Fragment(ipHeader)) {\r
+      return;\r
+    }\r
+    \r
+    udpHeader = (struct udphdr *)(encapsulationUdpData +\r
+                                  GetIpHeaderLength(encapsulationUdpData));\r
+    destPort = ntohs(udpHeader->dest);\r
+    \r
+    if (!InUdpDestPortList(AF_INET, &dst, destPort))\r
+       return;\r
+  }                            //END IPV4\r
+  else if ((encapsulationUdpData[0] & 0xf0) == 0x60) {  //IPv6\r
+\r
+    ipHeader6 = (struct ip6_hdr *)encapsulationUdpData;\r
+    \r
+    memcpy(&dst.v6, &ipHeader6->ip6_dst, sizeof(struct in6_addr));\r
+    \r
+    if (ipHeader6->ip6_dst.s6_addr[0] == 0xff)  //Multicast\r
+    {\r
+      //Continue\r
+    } else {\r
+      return;                   //not multicast\r
+    }\r
+    if (ipHeader6->ip6_nxt != SOL_UDP) {\r
+      /* Not UDP */\r
+      //OLSR_PRINTF(1,"NON UDP PACKET\n");\r
+      return;                   /* for */\r
+    }\r
+    \r
+    // Check whether this is a IPv6 fragment\r
+    if (IsIpv6Fragment(ipHeader6)) {\r
+      return;\r
+    }\r
+    \r
+    udpHeader = (struct udphdr *)(encapsulationUdpData + 40);\r
+    destPort = ntohs(udpHeader->dest);\r
+\r
+    if (!InUdpDestPortList(AF_INET6, &dst, destPort))\r
+      return;\r
+  }                             //END IPV6\r
+  else {\r
+    return;                     //Is not IP packet\r
+  }\r
+\r
+  /* Lookup main address of source in the MID table of OLSR */\r
+  origIp = MainAddressOf(&src);\r
+\r
+  // send the packet to OLSR forward mechanism\r
+  olsr_p2pd_gen(encapsulationUdpData, nBytes);\r
+}                               /* P2pdPacketCaptured */\r
+\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : DoP2pd\r
+ * Description: This function is registered with the OLSR scheduler and called when something is captured\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  :\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+DoP2pd(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))\r
+{\r
+  unsigned char rxBuffer[P2PD_BUFFER_SIZE];\r
+  if (skfd >= 0) {\r
+    struct sockaddr_ll pktAddr;\r
+    socklen_t addrLen = sizeof(pktAddr);\r
+    int nBytes;\r
+    unsigned char *ipPacket;\r
+\r
+    /* Receive the captured Ethernet frame, leaving space for the BMF\r
+     * encapsulation header */\r
+    ipPacket = GetIpPacket(rxBuffer);\r
+    nBytes = recvfrom(skfd, ipPacket, P2PD_BUFFER_SIZE,  //TODO: understand how to change this\r
+                      0, (struct sockaddr *)&pktAddr, &addrLen);\r
+    if (nBytes < 0) {\r
+\r
+      return;                   /* for */\r
+    }\r
+\r
+    /* if (nBytes < 0) */\r
+    /* Check if the number of received bytes is large enough for an IP\r
+     * packet which contains at least a minimum-size IP header.\r
+     * Note: There is an apparent bug in the packet socket implementation in\r
+     * combination with VLAN interfaces. On a VLAN interface, the value returned\r
+     * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value\r
+     * returned on a non-VLAN interface, for the same ethernet frame. */\r
+    if (nBytes < (int)sizeof(struct ip)) {\r
+      ////OLSR_PRINTF(\r
+      //              1,\r
+      //              "%s: captured frame too short (%d bytes) on \"%s\"\n",\r
+      //              PLUGIN_NAME,\r
+      //              nBytes,\r
+      //              walker->ifName);\r
+\r
+      return;                   /* for */\r
+    }\r
+\r
+    if (pktAddr.sll_pkttype == PACKET_OUTGOING ||\r
+        pktAddr.sll_pkttype == PACKET_MULTICAST ||\r
+        pktAddr.sll_pkttype == PACKET_BROADCAST) {\r
+      /* A multicast or broadcast packet was captured */\r
+\r
+      P2pdPacketCaptured(ipPacket, nBytes);\r
+\r
+    }                           /* if (pktAddr.sll_pkttype == ...) */\r
+  }                             /* if (skfd >= 0 && (FD_ISSET...)) */\r
+}                               /* DoP2pd */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : InitP2pd\r
+ * Description: Initialize the P2pd plugin\r
+ * Input      : skipThisInterface - pointer to interface to skip\r
+ * Output     : none\r
+ * Return     : Always 0\r
+ * Data Used  : none\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+InitP2pd(struct interface *skipThisIntf)\r
+{\r
+  // Initialize hash table for hash based duplicate IP packet check\r
+  InitPacketHistory();\r
+  \r
+  //Tells OLSR to launch olsr_parser when the packets for this plugin arrive\r
+  //olsr_parser_add_function(&olsr_parser, PARSER_TYPE,1);\r
+  olsr_parser_add_function(&olsr_parser, PARSER_TYPE);\r
+  \r
+  //Creates captures sockets and register them to the OLSR scheduler\r
+  CreateNonOlsrNetworkInterfaces(skipThisIntf);\r
+\r
+  return 0;\r
+}                               /* InitP2pd */\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : CloseP2pd\r
+ * Description: Close the P2pd plugin and clean up\r
+ * Input      : none\r
+ * Output     : none\r
+ * Return     : none\r
+ * Data Used  :\r
+ * ------------------------------------------------------------------------- */\r
+void\r
+CloseP2pd(void)\r
+{\r
+  CloseNonOlsrNetworkInterfaces();\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : SetP2pdTtl\r
+ * Description: Set the TTL for message from this plugin\r
+ * Input      : value - parameter value to evaluate\r
+ * Output     : none\r
+ * Return     : Always 0\r
+ * Data Used  : P2pdTtl\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+SetP2pdTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))\r
+{\r
+  assert(value != NULL);\r
+  P2pdTtl = atoi(value);\r
+\r
+  return 0;\r
+}\r
+\r
+bool is_broadcast(const struct sockaddr_in addr)\r
+{\r
+  if (addr.sin_addr.s_addr == 0xFFFFFFFF)\r
+    return true;\r
+    \r
+  return false;\r
+}\r
+\r
+bool is_multicast(const struct sockaddr_in addr)\r
+{\r
+  if ((htonl(addr.sin_addr.s_addr) & 0xE0000000) == 0xE0000000)\r
+    return true;\r
+\r
+  return false;\r
+}\r
+\r
+/* -------------------------------------------------------------------------\r
+ * Function   : AddUdpDestPort\r
+ * Description: Set the UDP destination/port combination as an entry in the\r
+ *              UdpDestPortList\r
+ * Input      : value - parameter value to evaluate\r
+ * Output     : none\r
+ * Return     : -1 on error condition, 0 if all is ok\r
+ * Data Used  : UdpDestPortList\r
+ * ------------------------------------------------------------------------- */\r
+int\r
+AddUdpDestPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))\r
+{\r
+  char destAddr[INET6_ADDRSTRLEN];\r
+  uint16_t destPort;\r
+  int num;\r
+  struct UdpDestPort *    new;\r
+  struct sockaddr_in      addr4;\r
+  struct sockaddr_in6     addr6;\r
+  int                     ip_version   = AF_INET;\r
+  int                     res;\r
+  \r
+  assert(value != NULL);\r
+  \r
+  // Retrieve the data from the argument string passed\r
+  memset(destAddr, 0, sizeof(destAddr));\r
+  num = sscanf(value, "%45s %hd", destAddr, &destPort);\r
+  if (num != 2) {\r
+    olsr_printf(1, "Invalid argument for \"UdpDestPort\"");\r
+    return -1;\r
+  }\r
+       \r
+  // Check whether we're dealing with an IPv4 or IPv6 address\r
+  // When the string contains a ':' we can assume we're dealing with IPv6\r
+  if (strchr(destAddr, (int)':')) {\r
+    ip_version = AF_INET6;\r
+  }\r
+\r
+  // Check whether the specified address was either IPv4 multicast,\r
+  // IPv4 broadcast or IPv6 multicast.\r
+\r
+  switch (ip_version) {\r
+  case AF_INET:\r
+    res = inet_pton(AF_INET, destAddr, &addr4.sin_addr);\r
+    if (!is_broadcast(addr4) && !is_multicast(addr4)) {\r
+      olsr_printf(1, "WARNING: IPv4 address must be multicast or broadcast... ");\r
+    }\r
+    break;\r
+  case AF_INET6:\r
+    res = inet_pton(AF_INET6, destAddr, &addr6.sin6_addr);\r
+    if (addr6.sin6_addr.s6_addr[0] != 0xFF) {\r
+      olsr_printf(1, "WARNING: IPv6 address must be multicast... ");\r
+      return -1;\r
+    }\r
+    break;\r
+  }\r
+  // Determine whether it is a valid IP address\r
+  if (res == 0) {\r
+    olsr_printf(1, "Invalid address specified for \"UdpDestPort\"");\r
+    return -1;\r
+  }\r
+       \r
+  // Create a new entry and link it into the chain\r
+  new = calloc(1, sizeof(struct UdpDestPort));\r
+  if (new == NULL) {\r
+    olsr_printf(1, "P2PD: Out of memory");\r
+    return -1;\r
+  }\r
+       \r
+  new->ip_version = ip_version;\r
+  switch (ip_version) {\r
+  case AF_INET:\r
+    new->address.v4.s_addr = addr4.sin_addr.s_addr;\r
+    break;\r
+  case AF_INET6:\r
+    memcpy(&new->address.v6.s6_addr, &addr6.sin6_addr.s6_addr, sizeof(sizeof(addr6.sin6_addr.s6_addr)));\r
+    break;\r
+  }\r
+  new->port = destPort;\r
+  new->next = UdpDestPortList;\r
+  UdpDestPortList = new;\r
+       \r
+  // And then we're done\r
+  return 0;\r
+}\r
+\r
index f59fe84..0e16b54 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * 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.
- *
- * 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.
- *
- * Visit http://www.olsr.org for more information.
- *
- * 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.
- *
- */
-
-
-#ifndef _P2PD_H
-#define _P2PD_H
-
-#define REMOVE_LOG_DEBUG
-
-#include "olsrd_plugin.h"             /* union set_plugin_parameter_addon */
-#include "duplicate_set.h"
-//#include "socket_parser.h"
-#include "dllist.h"
-
-#define P2PD_MESSAGE_TYPE         132
-#define PARSER_TYPE               P2PD_MESSAGE_TYPE
-#define P2PD_VALID_TIME           180          /* seconds */
-
-/* P2PD plugin data */
-#define PLUGIN_NAME               "OLSRD P2PD plugin"
-#define PLUGIN_NAME_SHORT         "OLSRD P2PD"
-#define PLUGIN_VERSION            "0.1.0 (" __DATE__ " " __TIME__ ")"
-#define MOD_DESC PLUGIN_NAME      " " PLUGIN_VERSION
-#define PLUGIN_INTERFACE_VERSION  5
-#define IPHDR_FRAGMENT_MASK       0xC000
-
-/* Forward declaration of OLSR interface type */
-struct interface;
-
-struct DupFilterEntry {
-  int                            ip_version;
-  union olsr_ip_addr             address;
-  uint16_t                       seqno;
-  uint8_t                        msgtype;
-  time_t                         creationtime;
-};
-
-struct UdpDestPort {
-  int                            ip_version;
-  union olsr_ip_addr             address;
-  uint16_t                       port;
-  struct UdpDestPort *           next;
-};
-
-extern int P2pdTtl;
-extern int P2pdDuplicateTimeout;
-extern int HighestSkfd;
-extern fd_set InputSet;
-extern struct UdpDestPort * UdpDestPortList;
-extern struct DuplicateFilterEntry * FilterList;
-
-void DoP2pd(int sd, void *x, unsigned int y);
-void P2pdPError(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
-union olsr_ip_addr *MainAddressOf(union olsr_ip_addr *ip);
-int InitP2pd(struct interface *skipThisIntf);
-void CloseP2pd(void);
-int SetP2pdTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));
-int AddUdpDestPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));
-bool InUdpDestPortList(int ip_version, union olsr_ip_addr *addr, uint16_t port);
-bool p2pd_message_seen(struct node **head, struct node **tail, union olsr_message *m);
-void p2pd_store_message(struct node **head, struct node **tail, union olsr_message *m);
-bool p2pd_is_duplicate_message(union olsr_message *msg);
-
-void olsr_p2pd_gen(unsigned char *packet, int len);
-
-/* Parser function to register with the scheduler */
-bool olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);
-
-#endif /* _P2PD_H */
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
+/*\r
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in\r
+ *   the documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * * Neither the name of olsr.org, olsrd nor the names of its\r
+ *   contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * Visit http://www.olsr.org for more information.\r
+ *\r
+ * If you find this software useful feel free to make a donation\r
+ * to the project. For more information see the website or contact\r
+ * the copyright holders.\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _P2PD_H\r
+#define _P2PD_H\r
+\r
+#define REMOVE_LOG_DEBUG\r
+\r
+#include "olsrd_plugin.h"             /* union set_plugin_parameter_addon */\r
+#include "duplicate_set.h"\r
+//#include "socket_parser.h"\r
+#include "dllist.h"\r
+\r
+#define P2PD_MESSAGE_TYPE         132\r
+#define PARSER_TYPE               P2PD_MESSAGE_TYPE\r
+#define P2PD_VALID_TIME           180          /* seconds */\r
+\r
+/* P2PD plugin data */\r
+#define PLUGIN_NAME               "OLSRD P2PD plugin"\r
+#define PLUGIN_NAME_SHORT         "OLSRD P2PD"\r
+#define PLUGIN_VERSION            "0.1.0 (" __DATE__ " " __TIME__ ")"\r
+#define MOD_DESC PLUGIN_NAME      " " PLUGIN_VERSION\r
+#define PLUGIN_INTERFACE_VERSION  5\r
+#define IPHDR_FRAGMENT_MASK       0xC000\r
+\r
+/* Forward declaration of OLSR interface type */\r
+struct interface;\r
+\r
+struct DupFilterEntry {\r
+  int                            ip_version;\r
+  union olsr_ip_addr             address;\r
+  uint16_t                       seqno;\r
+  uint8_t                        msgtype;\r
+  time_t                         creationtime;\r
+};\r
+\r
+struct UdpDestPort {\r
+  int                            ip_version;\r
+  union olsr_ip_addr             address;\r
+  uint16_t                       port;\r
+  struct UdpDestPort *           next;\r
+};\r
+\r
+extern int P2pdTtl;\r
+extern int P2pdDuplicateTimeout;\r
+extern int HighestSkfd;\r
+extern fd_set InputSet;\r
+extern struct UdpDestPort * UdpDestPortList;\r
+extern struct DuplicateFilterEntry * FilterList;\r
+\r
+void DoP2pd(int sd, void *x, unsigned int y);\r
+void P2pdPError(const char *format, ...) __attribute__ ((format(printf, 1, 2)));\r
+union olsr_ip_addr *MainAddressOf(union olsr_ip_addr *ip);\r
+int InitP2pd(struct interface *skipThisIntf);\r
+void CloseP2pd(void);\r
+int SetP2pdTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));\r
+int AddUdpDestPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));\r
+bool InUdpDestPortList(int ip_version, union olsr_ip_addr *addr, uint16_t port);\r
+bool p2pd_message_seen(struct node **head, struct node **tail, union olsr_message *m);\r
+void p2pd_store_message(struct node **head, struct node **tail, union olsr_message *m);\r
+bool p2pd_is_duplicate_message(union olsr_message *msg);\r
+\r
+void olsr_p2pd_gen(unsigned char *packet, int len);\r
+\r
+/* Parser function to register with the scheduler */\r
+bool olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);\r
+\r
+#endif /* _P2PD_H */\r
+\r
+/*\r
+ * Local Variables:\r
+ * c-basic-offset: 2\r
+ * indent-tabs-mode: nil\r
+ * End:\r
+ */\r