Change Windows (CRLF) to Unix (LF) line endings
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Thu, 18 Mar 2010 14:30:29 +0000 (15:30 +0100)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Thu, 18 Mar 2010 14:30:29 +0000 (15:30 +0100)
12 files changed:
lib/dyn_gw/src/olsrd_dyn_gw.c
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
lib/p2pd/src/PacketHistory.h
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 e5cc19d..231d3a3 100644 (file)
-\r
-/*\r
- * The olsr.org Optimized Link-State Routing daemon(olsrd)\r
- * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)\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
- * -Threaded ping code added by Jens Nachtigall\r
- * -HNA4 checking by bjoern riemer\r
- */\r
-\r
-#include <arpa/inet.h>\r
-\r
-#include "olsr_types.h"\r
-#include "olsrd_dyn_gw.h"\r
-#include "olsr.h"\r
-#include "defs.h"\r
-#include "ipcalc.h"\r
-#include "scheduler.h"\r
-#include "log.h"\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <sys/time.h>\r
-#include <net/route.h>\r
-#ifdef linux\r
-#include <linux/in_route.h>\r
-#endif\r
-#include <unistd.h>\r
-#include <errno.h>\r
-#include <time.h>\r
-#ifndef WIN32\r
-#include <pthread.h>\r
-#else\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-#undef interface\r
-\r
-#define close(x) closesocket(x)\r
-\r
-typedef HANDLE pthread_mutex_t;\r
-typedef HANDLE pthread_t;\r
-\r
-int pthread_create(HANDLE * Hand, void *Attr, void *(*Func) (void *), void *Arg);\r
-int pthread_kill(HANDLE Hand, int Sig);\r
-int pthread_mutex_init(HANDLE * Hand, void *Attr);\r
-int pthread_mutex_lock(HANDLE * Hand);\r
-int pthread_mutex_unlock(HANDLE * Hand);\r
-\r
-struct ThreadPara {\r
-  void *(*Func) (void *);\r
-  void *Arg;\r
-};\r
-#endif\r
-\r
-static int hna_check_interval  = DEFAULT_HNA_CHECK_INTERVAL;\r
-/* set default interval, in case none is given in the config file */\r
-static int ping_check_interval = DEFAULT_PING_CHECK_INTERVAL;\r
-\r
-/* list to store the Ping IP addresses given in the config file */\r
-struct ping_list {\r
-  char *ping_address;\r
-  struct ping_list *next;\r
-};\r
-\r
-static struct ping_list *add_to_ping_list(const char *, struct ping_list *);\r
-\r
-struct hna_list {\r
-  union olsr_ip_addr   hna_addr;\r
-  uint8_t              hna_prefixlen;\r
-  bool                 hna_added;\r
-  bool                 checked;\r
-  bool                 active;\r
-  struct hna_list *    next;\r
-};\r
-\r
-static struct hna_list *add_to_hna_list(struct hna_list *, union olsr_ip_addr *hna_addr, uint8_t hna_prefixlen);\r
-\r
-struct hna_group {\r
-  struct hna_list *    hna_list;\r
-  struct ping_list *   ping_hosts;\r
-  bool                 probe_ok;\r
-  struct hna_group *   next;\r
-};\r
-\r
-bool hna_ping_check    = false;\r
-static struct hna_group * hna_groups = NULL;\r
-\r
-static struct hna_group *add_to_hna_group(struct hna_group *);\r
-\r
-static void looped_checks(void *) __attribute__ ((noreturn));\r
-\r
-static bool check_gw(union olsr_ip_addr *, uint8_t, struct ping_list *);\r
-\r
-static int ping_is_possible(struct ping_list *);\r
-\r
-/* Event function to register with the scheduler */\r
-static void olsr_event_doing_hna(void *);\r
-\r
-struct hna_list* find_hna(uint32_t src_addr, uint32_t src_mask);\r
-\r
-char *get_ip_str(uint32_t address, char *s, size_t maxlen);\r
-int update_routing(void);\r
-\r
-/**\r
- * read config file parameters\r
- */\r
-static int\r
-set_plugin_ping(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))\r
-{\r
-  union olsr_ip_addr foo_addr;\r
-\r
-  if (inet_pton(olsr_cnf->ip_version, value, &foo_addr) <= 0) {\r
-    OLSR_PRINTF(0, "Illegal IP address \"%s\"", value);\r
-    return 1;\r
-  }\r
-\r
-  if (hna_groups == NULL) { \r
-    hna_groups = add_to_hna_group(hna_groups);\r
-    if (hna_groups == NULL)\r
-      return 1;\r
-  } else {\r
-    if (hna_groups->hna_list != NULL) {\r
-      hna_groups = add_to_hna_group(hna_groups);\r
-    }\r
-  }\r
-\r
-  hna_groups->ping_hosts = add_to_ping_list(value, hna_groups->ping_hosts);\r
-  hna_ping_check = true;\r
-  \r
-  return 0;\r
-}\r
-\r
-static int\r
-set_plugin_hna(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))\r
-{\r
-  union olsr_ip_addr temp_addr;\r
-  union olsr_ip_addr temp_mask;\r
-  char s_addr[128];\r
-  char s_mask[128];\r
-  \r
-  //Example: 192.168.1.0  255.255.255.0\r
-  int i = sscanf(value, "%127s %127s", s_addr, s_mask);\r
-  if (i != 2) {\r
-    OLSR_PRINTF(0, "Cannot get IP address and netmask from \"%s\"", value);\r
-    return 1;\r
-  }\r
-\r
-  if (inet_pton(olsr_cnf->ip_version, s_addr, &temp_addr) <= 0) {\r
-    OLSR_PRINTF(0, "Illegal IP address \"%s\"", s_addr);\r
-    return 1;\r
-  }\r
-\r
-  if (inet_pton(olsr_cnf->ip_version, s_mask, &temp_mask) <= 0) {\r
-    OLSR_PRINTF(0, "Illegal netmask \"%s\"", s_mask);\r
-    return 1;\r
-  }\r
-\r
-  if (hna_groups == NULL)\r
-  {\r
-    hna_groups = add_to_hna_group(hna_groups);\r
-    if (hna_groups == NULL) {\r
-      return 1;\r
-    }\r
-  }\r
-       \r
-  hna_groups->hna_list = add_to_hna_list(hna_groups->hna_list, &temp_addr, olsr_netmask_to_prefix(&temp_mask));\r
-  if (hna_groups->hna_list == NULL) {\r
-    return 1;\r
-  }\r
-  return 0;\r
-}\r
-\r
-static const struct olsrd_plugin_parameters plugin_parameters[] = {\r
-  {.name = "interval",      .set_plugin_parameter = &set_plugin_int,  .data = &ping_check_interval  },\r
-  {.name = "pinginterval",  .set_plugin_parameter = &set_plugin_int,  .data = &ping_check_interval  },\r
-  {.name = "checkinterval", .set_plugin_parameter = &set_plugin_int,  .data = &hna_check_interval   },\r
-  {.name = "ping",          .set_plugin_parameter = &set_plugin_ping, .data = NULL                  },\r
-  {.name = "hna",           .set_plugin_parameter = &set_plugin_hna,  .data = NULL                  },\r
-};\r
-\r
-void\r
-olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)\r
-{\r
-  *params = plugin_parameters;\r
-  *size = sizeof(plugin_parameters) / sizeof(*plugin_parameters);\r
-}\r
-\r
-/**\r
- *Do initialization here\r
- *\r
- *\r
- *This function is called by the my_init\r
- *function in uolsrd_plugin.c\r
- *It is ran _after_ register_olsr_param\r
- */\r
-int\r
-olsrd_plugin_init(void)\r
-{\r
-  pthread_t ping_thread;\r
-\r
-  if (hna_groups == NULL) {\r
-    hna_groups = add_to_hna_group(hna_groups);\r
-    if (hna_groups == NULL)\r
-      return 1;\r
-  }\r
-       \r
-  // Add a default gateway if the top entry was just a ping address\r
-  if (hna_groups->hna_list == NULL) {\r
-    union olsr_ip_addr temp_addr;\r
-    union olsr_ip_addr temp_mask;\r
-    \r
-    temp_addr.v4.s_addr = INET_ADDR;\r
-    temp_mask.v4.s_addr = INET_MASK;\r
-    hna_groups->hna_list = add_to_hna_list(hna_groups->hna_list, &temp_addr, olsr_netmask_to_prefix(&temp_mask));\r
-    if (hna_groups->hna_list == NULL) {\r
-      return 1;\r
-    }\r
-  }\r
-       \r
-  // Prepare all routing information\r
-  update_routing();\r
-  \r
-  if (hna_ping_check) {\r
-    pthread_create(&ping_thread, NULL, (void *(*)(void *))looped_checks, NULL);\r
-  } else {\r
-    struct hna_group *grp;\r
-    for (grp = hna_groups; grp; grp = grp->next) {\r
-      grp->probe_ok = true;\r
-    }\r
-  }\r
-\r
-  // Print the current configuration\r
-  {\r
-    struct hna_group *grp;\r
-    int i = 0;\r
-    for (grp = hna_groups; grp; grp = grp->next, ++i) {\r
-      struct hna_list *lst;\r
-      struct ping_list *png;\r
-           \r
-      olsr_printf(1, "Group %d:\n", i);\r
-      for (lst = grp->hna_list; lst; lst = lst->next) {\r
-        char addr[INET_ADDRSTRLEN];\r
-        olsr_printf(1, "  HNA %s\n", get_ip_str(lst->hna_addr.v4.s_addr, addr, INET_ADDRSTRLEN));\r
-      }\r
-      for (png = grp->ping_hosts; png; png = png->next) {\r
-        olsr_printf(1, "  PING %s\n", png->ping_address);\r
-      }\r
-    }\r
-  }\r
-\r
-  /* Register the GW check */\r
-  olsr_start_timer(hna_check_interval, 0, OLSR_TIMER_PERIODIC, &olsr_event_doing_hna, NULL, 0);\r
-  return 1;\r
-}\r
-\r
-/**\r
- * Scheduled event to update the hna table,\r
- * called from olsrd main thread to keep the hna table thread-safe\r
- */\r
-static void\r
-olsr_event_doing_hna(void *foo __attribute__ ((unused)))\r
-{\r
-  struct hna_group* grp;\r
-  struct hna_list *li;\r
-\r
-  update_routing();\r
-  \r
-  for (grp = hna_groups; grp; grp = grp->next) {\r
-    for (li = grp->hna_list; li; li = li->next) {\r
-      if (!li->hna_added) {\r
-        if (grp->probe_ok && li->active) {\r
-          olsr_printf(1, "Adding OLSR local HNA entry\n");\r
-          ip_prefix_list_add(&olsr_cnf->hna_entries, &li->hna_addr, li->hna_prefixlen);\r
-          li->hna_added = true;\r
-        }\r
-      } else {\r
-        if (!grp->probe_ok || !li->active) {\r
-          while (ip_prefix_list_remove(&olsr_cnf->hna_entries, &li->hna_addr, li->hna_prefixlen)) {\r
-            olsr_printf(1, "Removing OLSR local HNA entry\n");\r
-          }\r
-          li->hna_added = false;\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
- * the threaded function which happens within an endless loop,\r
- * reiterated every "Interval" sec (as given in the config or\r
- * the default value)\r
- */\r
-static void\r
-looped_checks(void *foo __attribute__ ((unused)))\r
-{\r
-  for (;;) {\r
-    struct hna_group *grp;\r
-    struct hna_list *li;\r
-    struct timespec remainder_spec;\r
-    /* the time to wait in "Interval" sec (see connfig), default=5sec */\r
-    struct timespec sleeptime_spec = { ping_check_interval, 0L };\r
-\r
-    for (grp = hna_groups; grp; grp = grp->next) {\r
-      for (li = grp->hna_list; li; li = li->next) {\r
-      \r
-               // If this HNA is not active skip to the next one\r
-        if (!li->active)\r
-          continue;\r
-          \r
-        /* check for gw in table entry and if Ping IPs are given also do pings */\r
-        grp->probe_ok = check_gw(&li->hna_addr, li->hna_prefixlen, grp->ping_hosts);\r
-        if (grp->probe_ok)\r
-          break;       // Valid host found so we can bail out of the inner loop here\r
-      }\r
-    }\r
-\r
-    while (nanosleep(&sleeptime_spec, &remainder_spec) < 0)\r
-      sleeptime_spec = remainder_spec;\r
-  }\r
-  // return NULL;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : find_hna\r
- * Description: Lookup an HNA that matches the specified parameters\r
- * Input      : src_addr - IP address of the HNA to find\r
- *              src_mask - Address mask of the HNA to find\r
- * Output     : none\r
- * Return     : The HNA specified or NULL when HNA not found\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-struct hna_list*\r
-find_hna(uint32_t src_addr, uint32_t src_mask)\r
-{\r
-  struct hna_group * grp;\r
-  struct hna_list *li;\r
-  union olsr_ip_addr mask;\r
-\r
-  for (grp = hna_groups; grp; grp = grp->next) {\r
-    for (li = grp->hna_list; li; li = li->next) {\r
-      olsr_prefix_to_netmask(&mask, li->hna_prefixlen);\r
-      if (li->hna_addr.v4.s_addr == src_addr && mask.v4.s_addr == src_mask) {\r
-        return li;\r
-      }\r
-    }\r
-  }\r
-  return NULL;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : get_ip_str\r
- * Description: Convert the specified address to an IPv4 compatible string\r
- * Input      : address - IPv4 address to convert to string \r
- *              s       - string buffer to contain the resulting string\r
- *              maxlen  - maximum length of the string buffer \r
- * Output     : none\r
- * Return     : Pointer to the string buffer containing the result\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-char *\r
-get_ip_str(uint32_t address, char *s, size_t maxlen)\r
-{\r
-  struct sockaddr_in v4;\r
-  \r
-  v4.sin_addr.s_addr = address;\r
-  inet_ntop(AF_INET, &v4.sin_addr, s, maxlen);\r
-\r
-  return s;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : update_routing\r
- * Description: Mark the HNAs in the HNA list(s) corresponding to the results\r
- *              found in the routing table. HNAs that are found in the routing\r
- *              table will be marked as 'active', otherwise they'll remain\r
- *              inactive.    \r
- * Input      : nothing\r
- * Output     : none\r
- * Return     : -1 if an error occurred, 0 otherwise\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-int \r
-update_routing(void)\r
-{\r
-  char buf[1024], iface[16];\r
-  uint32_t gate_addr, dest_addr, netmask;\r
-  unsigned int iflags;\r
-  int metric, refcnt, use;\r
-  struct hna_group *grp;\r
-  struct hna_list *li;\r
-  \r
-  FILE *fp = fopen(PROCENTRY_ROUTE, "r");\r
-  if (!fp) {\r
-    perror(PROCENTRY_ROUTE);\r
-    olsr_printf(1, "INET (IPv4) not configured in this system.\n");\r
-    return -1;\r
-  }\r
-\r
-  // Phase 1: reset the 'checked' flag, during the check of the routing table we \r
-  // will (re)discover whether the HNA is valid or not.\r
-  for (grp = hna_groups; grp; grp = grp->next) {\r
-    for (li = grp->hna_list; li; li = li->next) {\r
-      li->checked = false;\r
-    }\r
-  }\r
-\r
-  /*\r
-     olsr_printf(1, "Genmask         Destination     Gateway         "\r
-     "Flags Metric Ref    Use Iface\n");\r
-   */\r
-  while (fgets(buf, sizeof(buf), fp)) {\r
-    struct hna_list *hna;\r
-    char s_addr[INET_ADDRSTRLEN], s_mask[INET_ADDRSTRLEN];\r
-    \r
-    int num = sscanf(buf, \r
-                     "%15s %128X %128X %X %d %d %d %128X \n",\r
-                     iface, \r
-                     &dest_addr,\r
-                     &gate_addr,\r
-                     &iflags, \r
-                     &refcnt,\r
-                     &use,\r
-                     &metric,\r
-                     &netmask);\r
-    if (num < 8)\r
-      continue;\r
-\r
-    get_ip_str(dest_addr, s_addr, INET_ADDRSTRLEN);\r
-    get_ip_str(netmask, s_mask, INET_ADDRSTRLEN);\r
-    \r
-    hna = find_hna(dest_addr, netmask);\r
-    if (hna == NULL) { // Entry not found, try the next one\r
-      continue;\r
-    }\r
-    \r
-    if ((iflags & RTF_UP) && (metric == 0)) {\r
-      hna->checked = true;\r
-    }\r
-  }\r
-  fclose(fp);\r
-  \r
-  // Phase 2: now copy the 'checked' flag to the 'active' flag.\r
-  // The total check is a 2-phase process so the ping check loop won't be \r
-  // disturbed too badly.\r
-  for (grp = hna_groups; grp; grp = grp->next) {\r
-    for (li = grp->hna_list; li; li = li->next) {\r
-      li->active = li->checked;\r
-    }\r
-  }\r
-       \r
-  return 0;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : check_gw\r
- * Description: Check the specified gateway(s) by sending a ping\r
- * Input      : addr      - the address of the HNA to which the ping is related\r
- *              prefixlen - the length of the prefix for this HNA \r
- *              the_ping_list - list with related ping hosts\r
- * Output     : none\r
- * Return     : true if the ping host could be reached, false otherwise\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-static bool\r
-check_gw(union olsr_ip_addr *addr, uint8_t prefixlen, struct ping_list *the_ping_list)\r
-{\r
-  bool retval = false;\r
-  union olsr_ip_addr mask;\r
-\r
-  olsr_prefix_to_netmask(&mask, prefixlen);\r
-  \r
-  /* don't ping, if there was no "Ping" IP addr in the config file */\r
-  if (the_ping_list != NULL) {\r
-    /*validate the found inet gw by pinging */\r
-    if (ping_is_possible(the_ping_list)) {\r
-      olsr_printf(1, "HNA[%08x/%08x](ping is possible) detected in routing table.\n", addr->v4.s_addr, mask.v4.s_addr);\r
-      retval = true;\r
-    }\r
-  } else {\r
-    olsr_printf(1, "HNA[%08x/%08x] detected in routing table.\n", addr->v4.s_addr, mask.v4.s_addr);\r
-    retval = true;\r
-  }\r
-\r
-  if (retval == false) {\r
-    /* And we cast here since we get warnings on Win32 */\r
-    olsr_printf(1, "HNA[%08x/%08x] is invalid\n", (unsigned int)addr->v4.s_addr, (unsigned int)mask.v4.s_addr);\r
-  }\r
-  return retval;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : ping_is_possible\r
- * Description: Ping the specified host(s)\r
- * Input      : the_ping_list - the list of hosts to ping\r
- * Output     : none\r
- * Return     : 1 if any host responded, 0 otherwise\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-static int\r
-ping_is_possible(struct ping_list *the_ping_list)\r
-{\r
-  struct ping_list *list;\r
-  for (list = the_ping_list; list; list = list->next) {\r
-    char ping_command[50];\r
-    snprintf(ping_command, sizeof(ping_command), "ping -c 1 -q %s", list->ping_address);\r
-    olsr_printf(1, "\nDo ping on %s ...\n", list->ping_address);\r
-    if (system(ping_command) == 0) {\r
-      olsr_printf(1, "...OK\n\n");\r
-      return 1;\r
-    }\r
-    olsr_printf(1, "...FAILED\n\n");\r
-  }\r
-  return 0;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : add_to_ping_list\r
- * Description: Add a new ping host to the list of ping hosts\r
- * Input      : ping_address - the address of the ping host\r
- *              the_ping_list - the list of ping hosts \r
- * Output     : none\r
- * Return     : a pointer to the newly added ping host, i.e. start of the list\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-/* add the valid IPs to the head of the list */\r
-static struct ping_list *\r
-add_to_ping_list(const char *ping_address, struct ping_list *the_ping_list)\r
-{\r
-  struct ping_list *new = calloc(1, sizeof(struct ping_list));\r
-  if (!new) {\r
-    fprintf(stderr, "DYN GW: Out of memory!\n");\r
-    olsr_syslog(OLSR_LOG_ERR, "DYN GW: Out of memory!\n");\r
-    exit(0);\r
-  }\r
-  new->ping_address = strdup(ping_address);\r
-  new->next = the_ping_list;\r
-  return new;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : add_to_hna_list\r
- * Description: Add a new HNA entry to the list of HNA entries\r
- * Input      : list_root - the start of the list with HNA entries\r
- *              hna_addr  - the address of the new HNA entry\r
- *              prefixlen - the prefix-length of the new HNA entry \r
- * Output     : none\r
- * Return     : a pointer to the newly added HNA entry, i.e. start of the list\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-static struct hna_list *\r
-add_to_hna_list(struct hna_list *list_root, union olsr_ip_addr *hna_addr, uint8_t hna_prefixlen)\r
-{\r
-  struct hna_list *new = calloc(1, sizeof(struct hna_list));\r
-  if (new == NULL) {\r
-    fprintf(stderr, "DYN GW: Out of memory!\n");\r
-    olsr_syslog(OLSR_LOG_ERR, "DYN GW: Out of memory!\n");\r
-    exit(0);\r
-  }\r
-\r
-  new->hna_addr.v4 = hna_addr->v4;\r
-  new->hna_prefixlen = hna_prefixlen;\r
-  new->hna_added = false;\r
-  new->next = list_root;\r
-  return new;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : add_to_hna_group\r
- * Description: Add a new HNA group to the list of HNA groups\r
- * Input      : list_root - the start of the list with HNA groups\r
- * Output     : none\r
- * Return     : a pointer to the newly added HNA group, i.e. start of the list\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-static struct hna_group *\r
-add_to_hna_group(struct hna_group *list_root)\r
-{\r
-  struct hna_group *new = calloc(1, sizeof(struct hna_group));\r
-  if (new == NULL) {\r
-    fprintf(stderr, "DYN GW: Out of memory!\n");\r
-    olsr_syslog(OLSR_LOG_ERR, "DYN GW: Out of memory!\n");\r
-    exit(0);\r
-  }\r
-       \r
-  new->next =  list_root;\r
-  return new;\r
-}\r
-\r
-\r
-#ifdef WIN32\r
-\r
-/*\r
- * Windows pthread compat stuff\r
- */\r
-static unsigned long __stdcall\r
-ThreadWrapper(void *Para)\r
-{\r
-  struct ThreadPara *Cast;\r
-  void *(*Func) (void *);\r
-  void *Arg;\r
-\r
-  Cast = (struct ThreadPara *)Para;\r
-\r
-  Func = Cast->Func;\r
-  Arg = Cast->Arg;\r
-\r
-  HeapFree(GetProcessHeap(), 0, Para);\r
-\r
-  Func(Arg);\r
-\r
-  return 0;\r
-}\r
-\r
-int\r
-pthread_create(HANDLE * Hand, void *Attr __attribute__ ((unused)), void *(*Func) (void *), void *Arg)\r
-{\r
-  struct ThreadPara *Para;\r
-  unsigned long ThreadId;\r
-\r
-  Para = HeapAlloc(GetProcessHeap(), 0, sizeof(struct ThreadPara));\r
-\r
-  if (Para == NULL)\r
-    return -1;\r
-\r
-  Para->Func = Func;\r
-  Para->Arg = Arg;\r
-\r
-  *Hand = CreateThread(NULL, 0, ThreadWrapper, Para, 0, &ThreadId);\r
-\r
-  if (*Hand == NULL)\r
-    return -1;\r
-\r
-  return 0;\r
-}\r
-\r
-int\r
-pthread_kill(HANDLE Hand, int Sig __attribute__ ((unused)))\r
-{\r
-  if (!TerminateThread(Hand, 0))\r
-    return -1;\r
-\r
-  return 0;\r
-}\r
-\r
-int\r
-pthread_mutex_init(HANDLE * Hand, void *Attr __attribute__ ((unused)))\r
-{\r
-  *Hand = CreateMutex(NULL, FALSE, NULL);\r
-\r
-  if (*Hand == NULL)\r
-    return -1;\r
-\r
-  return 0;\r
-}\r
-\r
-int\r
-pthread_mutex_lock(HANDLE * Hand)\r
-{\r
-  if (WaitForSingleObject(*Hand, INFINITE) == WAIT_FAILED)\r
-    return -1;\r
-\r
-  return 0;\r
-}\r
-\r
-int\r
-pthread_mutex_unlock(HANDLE * Hand)\r
-{\r
-  if (!ReleaseMutex(*Hand))\r
-    return -1;\r
-\r
-  return 0;\r
-}\r
-\r
-#endif\r
-\r
-/*\r
- * Local Variables:\r
- * c-basic-offset: 2\r
- * indent-tabs-mode: nil\r
- * End:\r
- */\r
+
+/*
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
+ * 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.
+ *
+ */
+
+/*
+ * -Threaded ping code added by Jens Nachtigall
+ * -HNA4 checking by bjoern riemer
+ */
+
+#include <arpa/inet.h>
+
+#include "olsr_types.h"
+#include "olsrd_dyn_gw.h"
+#include "olsr.h"
+#include "defs.h"
+#include "ipcalc.h"
+#include "scheduler.h"
+#include "log.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <net/route.h>
+#ifdef linux
+#include <linux/in_route.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#ifndef WIN32
+#include <pthread.h>
+#else
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef interface
+
+#define close(x) closesocket(x)
+
+typedef HANDLE pthread_mutex_t;
+typedef HANDLE pthread_t;
+
+int pthread_create(HANDLE * Hand, void *Attr, void *(*Func) (void *), void *Arg);
+int pthread_kill(HANDLE Hand, int Sig);
+int pthread_mutex_init(HANDLE * Hand, void *Attr);
+int pthread_mutex_lock(HANDLE * Hand);
+int pthread_mutex_unlock(HANDLE * Hand);
+
+struct ThreadPara {
+  void *(*Func) (void *);
+  void *Arg;
+};
+#endif
+
+static int hna_check_interval  = DEFAULT_HNA_CHECK_INTERVAL;
+/* set default interval, in case none is given in the config file */
+static int ping_check_interval = DEFAULT_PING_CHECK_INTERVAL;
+
+/* list to store the Ping IP addresses given in the config file */
+struct ping_list {
+  char *ping_address;
+  struct ping_list *next;
+};
+
+static struct ping_list *add_to_ping_list(const char *, struct ping_list *);
+
+struct hna_list {
+  union olsr_ip_addr   hna_addr;
+  uint8_t              hna_prefixlen;
+  bool                 hna_added;
+  bool                 checked;
+  bool                 active;
+  struct hna_list *    next;
+};
+
+static struct hna_list *add_to_hna_list(struct hna_list *, union olsr_ip_addr *hna_addr, uint8_t hna_prefixlen);
+
+struct hna_group {
+  struct hna_list *    hna_list;
+  struct ping_list *   ping_hosts;
+  bool                 probe_ok;
+  struct hna_group *   next;
+};
+
+bool hna_ping_check    = false;
+static struct hna_group * hna_groups = NULL;
+
+static struct hna_group *add_to_hna_group(struct hna_group *);
+
+static void looped_checks(void *) __attribute__ ((noreturn));
+
+static bool check_gw(union olsr_ip_addr *, uint8_t, struct ping_list *);
+
+static int ping_is_possible(struct ping_list *);
+
+/* Event function to register with the scheduler */
+static void olsr_event_doing_hna(void *);
+
+struct hna_list* find_hna(uint32_t src_addr, uint32_t src_mask);
+
+char *get_ip_str(uint32_t address, char *s, size_t maxlen);
+int update_routing(void);
+
+/**
+ * read config file parameters
+ */
+static int
+set_plugin_ping(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+{
+  union olsr_ip_addr foo_addr;
+
+  if (inet_pton(olsr_cnf->ip_version, value, &foo_addr) <= 0) {
+    OLSR_PRINTF(0, "Illegal IP address \"%s\"", value);
+    return 1;
+  }
+
+  if (hna_groups == NULL) { 
+    hna_groups = add_to_hna_group(hna_groups);
+    if (hna_groups == NULL)
+      return 1;
+  } else {
+    if (hna_groups->hna_list != NULL) {
+      hna_groups = add_to_hna_group(hna_groups);
+    }
+  }
+
+  hna_groups->ping_hosts = add_to_ping_list(value, hna_groups->ping_hosts);
+  hna_ping_check = true;
+  
+  return 0;
+}
+
+static int
+set_plugin_hna(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+{
+  union olsr_ip_addr temp_addr;
+  union olsr_ip_addr temp_mask;
+  char s_addr[128];
+  char s_mask[128];
+  
+  //Example: 192.168.1.0  255.255.255.0
+  int i = sscanf(value, "%127s %127s", s_addr, s_mask);
+  if (i != 2) {
+    OLSR_PRINTF(0, "Cannot get IP address and netmask from \"%s\"", value);
+    return 1;
+  }
+
+  if (inet_pton(olsr_cnf->ip_version, s_addr, &temp_addr) <= 0) {
+    OLSR_PRINTF(0, "Illegal IP address \"%s\"", s_addr);
+    return 1;
+  }
+
+  if (inet_pton(olsr_cnf->ip_version, s_mask, &temp_mask) <= 0) {
+    OLSR_PRINTF(0, "Illegal netmask \"%s\"", s_mask);
+    return 1;
+  }
+
+  if (hna_groups == NULL)
+  {
+    hna_groups = add_to_hna_group(hna_groups);
+    if (hna_groups == NULL) {
+      return 1;
+    }
+  }
+       
+  hna_groups->hna_list = add_to_hna_list(hna_groups->hna_list, &temp_addr, olsr_netmask_to_prefix(&temp_mask));
+  if (hna_groups->hna_list == NULL) {
+    return 1;
+  }
+  return 0;
+}
+
+static const struct olsrd_plugin_parameters plugin_parameters[] = {
+  {.name = "interval",      .set_plugin_parameter = &set_plugin_int,  .data = &ping_check_interval  },
+  {.name = "pinginterval",  .set_plugin_parameter = &set_plugin_int,  .data = &ping_check_interval  },
+  {.name = "checkinterval", .set_plugin_parameter = &set_plugin_int,  .data = &hna_check_interval   },
+  {.name = "ping",          .set_plugin_parameter = &set_plugin_ping, .data = NULL                  },
+  {.name = "hna",           .set_plugin_parameter = &set_plugin_hna,  .data = NULL                  },
+};
+
+void
+olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
+{
+  *params = plugin_parameters;
+  *size = sizeof(plugin_parameters) / sizeof(*plugin_parameters);
+}
+
+/**
+ *Do initialization here
+ *
+ *
+ *This function is called by the my_init
+ *function in uolsrd_plugin.c
+ *It is ran _after_ register_olsr_param
+ */
+int
+olsrd_plugin_init(void)
+{
+  pthread_t ping_thread;
+
+  if (hna_groups == NULL) {
+    hna_groups = add_to_hna_group(hna_groups);
+    if (hna_groups == NULL)
+      return 1;
+  }
+       
+  // Add a default gateway if the top entry was just a ping address
+  if (hna_groups->hna_list == NULL) {
+    union olsr_ip_addr temp_addr;
+    union olsr_ip_addr temp_mask;
+    
+    temp_addr.v4.s_addr = INET_ADDR;
+    temp_mask.v4.s_addr = INET_MASK;
+    hna_groups->hna_list = add_to_hna_list(hna_groups->hna_list, &temp_addr, olsr_netmask_to_prefix(&temp_mask));
+    if (hna_groups->hna_list == NULL) {
+      return 1;
+    }
+  }
+       
+  // Prepare all routing information
+  update_routing();
+  
+  if (hna_ping_check) {
+    pthread_create(&ping_thread, NULL, (void *(*)(void *))looped_checks, NULL);
+  } else {
+    struct hna_group *grp;
+    for (grp = hna_groups; grp; grp = grp->next) {
+      grp->probe_ok = true;
+    }
+  }
+
+  // Print the current configuration
+  {
+    struct hna_group *grp;
+    int i = 0;
+    for (grp = hna_groups; grp; grp = grp->next, ++i) {
+      struct hna_list *lst;
+      struct ping_list *png;
+           
+      olsr_printf(1, "Group %d:\n", i);
+      for (lst = grp->hna_list; lst; lst = lst->next) {
+        char addr[INET_ADDRSTRLEN];
+        olsr_printf(1, "  HNA %s\n", get_ip_str(lst->hna_addr.v4.s_addr, addr, INET_ADDRSTRLEN));
+      }
+      for (png = grp->ping_hosts; png; png = png->next) {
+        olsr_printf(1, "  PING %s\n", png->ping_address);
+      }
+    }
+  }
+
+  /* Register the GW check */
+  olsr_start_timer(hna_check_interval, 0, OLSR_TIMER_PERIODIC, &olsr_event_doing_hna, NULL, 0);
+  return 1;
+}
+
+/**
+ * Scheduled event to update the hna table,
+ * called from olsrd main thread to keep the hna table thread-safe
+ */
+static void
+olsr_event_doing_hna(void *foo __attribute__ ((unused)))
+{
+  struct hna_group* grp;
+  struct hna_list *li;
+
+  update_routing();
+  
+  for (grp = hna_groups; grp; grp = grp->next) {
+    for (li = grp->hna_list; li; li = li->next) {
+      if (!li->hna_added) {
+        if (grp->probe_ok && li->active) {
+          olsr_printf(1, "Adding OLSR local HNA entry\n");
+          ip_prefix_list_add(&olsr_cnf->hna_entries, &li->hna_addr, li->hna_prefixlen);
+          li->hna_added = true;
+        }
+      } else {
+        if (!grp->probe_ok || !li->active) {
+          while (ip_prefix_list_remove(&olsr_cnf->hna_entries, &li->hna_addr, li->hna_prefixlen)) {
+            olsr_printf(1, "Removing OLSR local HNA entry\n");
+          }
+          li->hna_added = false;
+        }
+      }
+    }
+  }
+}
+
+/**
+ * the threaded function which happens within an endless loop,
+ * reiterated every "Interval" sec (as given in the config or
+ * the default value)
+ */
+static void
+looped_checks(void *foo __attribute__ ((unused)))
+{
+  for (;;) {
+    struct hna_group *grp;
+    struct hna_list *li;
+    struct timespec remainder_spec;
+    /* the time to wait in "Interval" sec (see connfig), default=5sec */
+    struct timespec sleeptime_spec = { ping_check_interval, 0L };
+
+    for (grp = hna_groups; grp; grp = grp->next) {
+      for (li = grp->hna_list; li; li = li->next) {
+      
+               // If this HNA is not active skip to the next one
+        if (!li->active)
+          continue;
+          
+        /* check for gw in table entry and if Ping IPs are given also do pings */
+        grp->probe_ok = check_gw(&li->hna_addr, li->hna_prefixlen, grp->ping_hosts);
+        if (grp->probe_ok)
+          break;       // Valid host found so we can bail out of the inner loop here
+      }
+    }
+
+    while (nanosleep(&sleeptime_spec, &remainder_spec) < 0)
+      sleeptime_spec = remainder_spec;
+  }
+  // return NULL;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : find_hna
+ * Description: Lookup an HNA that matches the specified parameters
+ * Input      : src_addr - IP address of the HNA to find
+ *              src_mask - Address mask of the HNA to find
+ * Output     : none
+ * Return     : The HNA specified or NULL when HNA not found
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+struct hna_list*
+find_hna(uint32_t src_addr, uint32_t src_mask)
+{
+  struct hna_group * grp;
+  struct hna_list *li;
+  union olsr_ip_addr mask;
+
+  for (grp = hna_groups; grp; grp = grp->next) {
+    for (li = grp->hna_list; li; li = li->next) {
+      olsr_prefix_to_netmask(&mask, li->hna_prefixlen);
+      if (li->hna_addr.v4.s_addr == src_addr && mask.v4.s_addr == src_mask) {
+        return li;
+      }
+    }
+  }
+  return NULL;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : get_ip_str
+ * Description: Convert the specified address to an IPv4 compatible string
+ * Input      : address - IPv4 address to convert to string 
+ *              s       - string buffer to contain the resulting string
+ *              maxlen  - maximum length of the string buffer 
+ * Output     : none
+ * Return     : Pointer to the string buffer containing the result
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+char *
+get_ip_str(uint32_t address, char *s, size_t maxlen)
+{
+  struct sockaddr_in v4;
+  
+  v4.sin_addr.s_addr = address;
+  inet_ntop(AF_INET, &v4.sin_addr, s, maxlen);
+
+  return s;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : update_routing
+ * Description: Mark the HNAs in the HNA list(s) corresponding to the results
+ *              found in the routing table. HNAs that are found in the routing
+ *              table will be marked as 'active', otherwise they'll remain
+ *              inactive.    
+ * Input      : nothing
+ * Output     : none
+ * Return     : -1 if an error occurred, 0 otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+int 
+update_routing(void)
+{
+  char buf[1024], iface[16];
+  uint32_t gate_addr, dest_addr, netmask;
+  unsigned int iflags;
+  int metric, refcnt, use;
+  struct hna_group *grp;
+  struct hna_list *li;
+  
+  FILE *fp = fopen(PROCENTRY_ROUTE, "r");
+  if (!fp) {
+    perror(PROCENTRY_ROUTE);
+    olsr_printf(1, "INET (IPv4) not configured in this system.\n");
+    return -1;
+  }
+
+  // Phase 1: reset the 'checked' flag, during the check of the routing table we 
+  // will (re)discover whether the HNA is valid or not.
+  for (grp = hna_groups; grp; grp = grp->next) {
+    for (li = grp->hna_list; li; li = li->next) {
+      li->checked = false;
+    }
+  }
+
+  /*
+     olsr_printf(1, "Genmask         Destination     Gateway         "
+     "Flags Metric Ref    Use Iface\n");
+   */
+  while (fgets(buf, sizeof(buf), fp)) {
+    struct hna_list *hna;
+    char s_addr[INET_ADDRSTRLEN], s_mask[INET_ADDRSTRLEN];
+    
+    int num = sscanf(buf, 
+                     "%15s %128X %128X %X %d %d %d %128X \n",
+                     iface, 
+                     &dest_addr,
+                     &gate_addr,
+                     &iflags, 
+                     &refcnt,
+                     &use,
+                     &metric,
+                     &netmask);
+    if (num < 8)
+      continue;
+
+    get_ip_str(dest_addr, s_addr, INET_ADDRSTRLEN);
+    get_ip_str(netmask, s_mask, INET_ADDRSTRLEN);
+    
+    hna = find_hna(dest_addr, netmask);
+    if (hna == NULL) { // Entry not found, try the next one
+      continue;
+    }
+    
+    if ((iflags & RTF_UP) && (metric == 0)) {
+      hna->checked = true;
+    }
+  }
+  fclose(fp);
+  
+  // Phase 2: now copy the 'checked' flag to the 'active' flag.
+  // The total check is a 2-phase process so the ping check loop won't be 
+  // disturbed too badly.
+  for (grp = hna_groups; grp; grp = grp->next) {
+    for (li = grp->hna_list; li; li = li->next) {
+      li->active = li->checked;
+    }
+  }
+       
+  return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : check_gw
+ * Description: Check the specified gateway(s) by sending a ping
+ * Input      : addr      - the address of the HNA to which the ping is related
+ *              prefixlen - the length of the prefix for this HNA 
+ *              the_ping_list - list with related ping hosts
+ * Output     : none
+ * Return     : true if the ping host could be reached, false otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+static bool
+check_gw(union olsr_ip_addr *addr, uint8_t prefixlen, struct ping_list *the_ping_list)
+{
+  bool retval = false;
+  union olsr_ip_addr mask;
+
+  olsr_prefix_to_netmask(&mask, prefixlen);
+  
+  /* don't ping, if there was no "Ping" IP addr in the config file */
+  if (the_ping_list != NULL) {
+    /*validate the found inet gw by pinging */
+    if (ping_is_possible(the_ping_list)) {
+      olsr_printf(1, "HNA[%08x/%08x](ping is possible) detected in routing table.\n", addr->v4.s_addr, mask.v4.s_addr);
+      retval = true;
+    }
+  } else {
+    olsr_printf(1, "HNA[%08x/%08x] detected in routing table.\n", addr->v4.s_addr, mask.v4.s_addr);
+    retval = true;
+  }
+
+  if (retval == false) {
+    /* And we cast here since we get warnings on Win32 */
+    olsr_printf(1, "HNA[%08x/%08x] is invalid\n", (unsigned int)addr->v4.s_addr, (unsigned int)mask.v4.s_addr);
+  }
+  return retval;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : ping_is_possible
+ * Description: Ping the specified host(s)
+ * Input      : the_ping_list - the list of hosts to ping
+ * Output     : none
+ * Return     : 1 if any host responded, 0 otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+static int
+ping_is_possible(struct ping_list *the_ping_list)
+{
+  struct ping_list *list;
+  for (list = the_ping_list; list; list = list->next) {
+    char ping_command[50];
+    snprintf(ping_command, sizeof(ping_command), "ping -c 1 -q %s", list->ping_address);
+    olsr_printf(1, "\nDo ping on %s ...\n", list->ping_address);
+    if (system(ping_command) == 0) {
+      olsr_printf(1, "...OK\n\n");
+      return 1;
+    }
+    olsr_printf(1, "...FAILED\n\n");
+  }
+  return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : add_to_ping_list
+ * Description: Add a new ping host to the list of ping hosts
+ * Input      : ping_address - the address of the ping host
+ *              the_ping_list - the list of ping hosts 
+ * Output     : none
+ * Return     : a pointer to the newly added ping host, i.e. start of the list
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+/* add the valid IPs to the head of the list */
+static struct ping_list *
+add_to_ping_list(const char *ping_address, struct ping_list *the_ping_list)
+{
+  struct ping_list *new = calloc(1, sizeof(struct ping_list));
+  if (!new) {
+    fprintf(stderr, "DYN GW: Out of memory!\n");
+    olsr_syslog(OLSR_LOG_ERR, "DYN GW: Out of memory!\n");
+    exit(0);
+  }
+  new->ping_address = strdup(ping_address);
+  new->next = the_ping_list;
+  return new;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : add_to_hna_list
+ * Description: Add a new HNA entry to the list of HNA entries
+ * Input      : list_root - the start of the list with HNA entries
+ *              hna_addr  - the address of the new HNA entry
+ *              prefixlen - the prefix-length of the new HNA entry 
+ * Output     : none
+ * Return     : a pointer to the newly added HNA entry, i.e. start of the list
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+static struct hna_list *
+add_to_hna_list(struct hna_list *list_root, union olsr_ip_addr *hna_addr, uint8_t hna_prefixlen)
+{
+  struct hna_list *new = calloc(1, sizeof(struct hna_list));
+  if (new == NULL) {
+    fprintf(stderr, "DYN GW: Out of memory!\n");
+    olsr_syslog(OLSR_LOG_ERR, "DYN GW: Out of memory!\n");
+    exit(0);
+  }
+
+  new->hna_addr.v4 = hna_addr->v4;
+  new->hna_prefixlen = hna_prefixlen;
+  new->hna_added = false;
+  new->next = list_root;
+  return new;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : add_to_hna_group
+ * Description: Add a new HNA group to the list of HNA groups
+ * Input      : list_root - the start of the list with HNA groups
+ * Output     : none
+ * Return     : a pointer to the newly added HNA group, i.e. start of the list
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+static struct hna_group *
+add_to_hna_group(struct hna_group *list_root)
+{
+  struct hna_group *new = calloc(1, sizeof(struct hna_group));
+  if (new == NULL) {
+    fprintf(stderr, "DYN GW: Out of memory!\n");
+    olsr_syslog(OLSR_LOG_ERR, "DYN GW: Out of memory!\n");
+    exit(0);
+  }
+       
+  new->next =  list_root;
+  return new;
+}
+
+
+#ifdef WIN32
+
+/*
+ * Windows pthread compat stuff
+ */
+static unsigned long __stdcall
+ThreadWrapper(void *Para)
+{
+  struct ThreadPara *Cast;
+  void *(*Func) (void *);
+  void *Arg;
+
+  Cast = (struct ThreadPara *)Para;
+
+  Func = Cast->Func;
+  Arg = Cast->Arg;
+
+  HeapFree(GetProcessHeap(), 0, Para);
+
+  Func(Arg);
+
+  return 0;
+}
+
+int
+pthread_create(HANDLE * Hand, void *Attr __attribute__ ((unused)), void *(*Func) (void *), void *Arg)
+{
+  struct ThreadPara *Para;
+  unsigned long ThreadId;
+
+  Para = HeapAlloc(GetProcessHeap(), 0, sizeof(struct ThreadPara));
+
+  if (Para == NULL)
+    return -1;
+
+  Para->Func = Func;
+  Para->Arg = Arg;
+
+  *Hand = CreateThread(NULL, 0, ThreadWrapper, Para, 0, &ThreadId);
+
+  if (*Hand == NULL)
+    return -1;
+
+  return 0;
+}
+
+int
+pthread_kill(HANDLE Hand, int Sig __attribute__ ((unused)))
+{
+  if (!TerminateThread(Hand, 0))
+    return -1;
+
+  return 0;
+}
+
+int
+pthread_mutex_init(HANDLE * Hand, void *Attr __attribute__ ((unused)))
+{
+  *Hand = CreateMutex(NULL, FALSE, NULL);
+
+  if (*Hand == NULL)
+    return -1;
+
+  return 0;
+}
+
+int
+pthread_mutex_lock(HANDLE * Hand)
+{
+  if (WaitForSingleObject(*Hand, INFINITE) == WAIT_FAILED)
+    return -1;
+
+  return 0;
+}
+
+int
+pthread_mutex_unlock(HANDLE * Hand)
+{
+  if (!ReleaseMutex(*Hand))
+    return -1;
+
+  return 0;
+}
+
+#endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */
index 164334d..c767b16 100644 (file)
-/*\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
+/*
+ * 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 */
index 1c65269..46a1a0b 100644 (file)
-/*\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
+/*
+ * 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:
+ */
index b163038..7612b61 100644 (file)
-/*\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 __attribute__ ((unused)))\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 __attribute__ ((unused)))\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
+/*
+ * 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   : IsIpFragment
+ * 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 IsIpFragment(unsigned char* ipPacket)
+{
+  struct ip* iph;
+
+  assert(ipPacket != NULL);
+
+  iph = (struct ip*) ipPacket;
+  if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
+  {
+    return 1;
+  }
+  return 0;
+} /* IsIpFragment */
+
+/* -------------------------------------------------------------------------
+ * Function   : GetIpTotalLength
+ * Description: Retrieve the total length of the IP packet (in bytes) of
+ *              an IP packet
+ * Input      : ipPacket - the IP packet
+ * Output     : none
+ * Return     : IP packet length
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+u_int16_t GetIpTotalLength(unsigned char* ipPacket)
+{
+  struct iphdr* iph;
+
+  assert(ipPacket != NULL);
+
+  iph = (struct iphdr*) ipPacket;
+  return ntohs(iph->tot_len);
+} /* GetIpTotalLength */
+
+/* -------------------------------------------------------------------------
+ * 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 __attribute__ ((unused)))
+{
+  assert(hdr != NULL);
+  
+//#error Implementation required
+  if (0)
+    return 1;
+    
+  return 0;
+}
+
+int IsMulticastv6(struct ip6_hdr* hdr __attribute__ ((unused)))
+{
+  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 */
+
+/* -------------------------------------------------------------------------
+ * Function   : GetTtl
+ * Description: Retrieve the TTL (Time To Live) value from the IP header of
+ *              an IP packet
+ * Input      : ipPacket - the IP packet
+ * Output     : none
+ * Return     : TTL value
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+u_int8_t GetTtl(unsigned char* ipPacket)
+{
+  struct iphdr* iph;
+
+  assert(ipPacket != NULL);
+
+  iph = (struct iphdr*) ipPacket;
+  return iph->ttl;
+} /* GetTtl */
+
+/* -------------------------------------------------------------------------
+ * Function   : SaveTtlAndChecksum
+ * Description: Save the TTL (Time To Live) value and IP checksum as found in
+ *              the IP header of an IP packet
+ * Input      : ipPacket - the IP packet
+ * Output     : sttl - the TTL and checksum values
+ * Return     : none
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
+{
+  struct iphdr* iph;
+
+  assert(ipPacket != NULL && sttl != NULL);
+
+  iph = (struct iphdr*) ipPacket;
+  sttl->ttl = iph->ttl;
+  sttl->check = ntohs(iph->check);
+} /* SaveTtlAndChecksum */
+
+/* -------------------------------------------------------------------------
+ * Function   : RestoreTtlAndChecksum
+ * Description: Restore the TTL (Time To Live) value and IP checksum in
+ *              the IP header of an IP packet
+ * Input      : ipPacket - the IP packet
+ *              sttl - the TTL and checksum values
+ * Output     : none
+ * Return     : none
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
+{
+  struct iphdr* iph;
+
+  assert(ipPacket != NULL && sttl != NULL);
+
+  iph = (struct iphdr*) ipPacket;
+  iph->ttl = sttl->ttl;
+  iph->check = htons(sttl->check);
+} /* RestoreTtlAndChecksum */
+
+/* -------------------------------------------------------------------------
+ * Function   : DecreaseTtlAndUpdateHeaderChecksum
+ * Description: For an IP packet, decrement the TTL value and update the IP header
+ *              checksum accordingly.
+ * Input      : ipPacket - the IP packet
+ * Output     : none
+ * Return     : none
+ * Data Used  : none
+ * Notes      : See also RFC1141
+ * ------------------------------------------------------------------------- */
+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
+{
+  struct iphdr* iph;
+  u_int32_t sum;
+
+  assert(ipPacket != NULL);
+
+  iph = (struct iphdr*) ipPacket;
+
+  iph->ttl--; /* decrement ttl */
+  sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
+  iph->check = htons(sum + (sum>>16)); /* add carry */
+} /* DecreaseTtlAndUpdateHeaderChecksum */
+
+
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */
index 4c3ad58..eff3cfd 100644 (file)
@@ -1,85 +1,85 @@
-/*\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
+/*
+ * 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 */
+
+struct TSaveTtl
+{
+  u_int8_t ttl;
+  u_int16_t check;
+} __attribute__((__packed__));
+
+/* 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 IsIpFragment(unsigned char* ipPacket);
+u_int16_t GetIpTotalLength(unsigned char* ipPacket);
+int IsIpv4Fragment(struct ip*);
+int IsMulticastv4(struct ip*);
+int IsBroadcast(struct ip*);
+int IsIpv6Fragment(struct ip6_hdr*);
+int IsMulticastv6(struct ip6_hdr*);
+u_int8_t GetTtl(unsigned char* ipPacket);
+void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
+void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket);
+unsigned int GetIpHeaderLength(unsigned char *ipPacket);
+unsigned char *GetIpPacket(unsigned char *encapsulationUdpData);
+
+#endif /* _P2PD_PACKET_H */
index 3db6490..295e6a4 100644 (file)
-/*\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), "OLSRD P2PD: 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
+/*
+ * OLSR Basic Multicast Forwarding (BMF) plugin.
+ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
+ * Written by Erik Tromp.
+ * 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 Thales, BMF 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File       : PacketHistory.c
+ * Description: Functions for keeping and accessing the history of processed
+ *              multicast IP packets.
+ * Created    : 29 Jun 2006
+ *
+ * ------------------------------------------------------------------------- */
+
+#include "PacketHistory.h"
+
+/* System includes */
+#include <stddef.h> /* NULL */
+#include <assert.h> /* assert() */
+#include <string.h> /* memset */
+#include <sys/types.h> /* u_int16_t, u_int32_t */
+#include <netinet/ip.h> /* struct iphdr */
+#include <stdlib.h> /* free() */
+
+/* OLSRD includes */
+#include "olsr.h" /* olsr_printf */
+#include "scheduler.h" /* GET_TIMESTAMP, TIMED_OUT */
+
+/* Plugin includes */
+#include "Packet.h"
+
+static struct TDupEntry* PacketHistory[HISTORY_HASH_SIZE];
+
+#define CRC_UPTO_NBYTES 256
+
+#if 0
+/* -------------------------------------------------------------------------
+ * Function   : CalcCrcCcitt
+ * Description: Calculate 16-bits CRC according to CRC-CCITT specification
+ * Input      : buffer - the bytes to calculate the CRC value over
+ *              len - the number of bytes to calculate the CRC value over
+ * Output     : none
+ * Return     : CRC-16 value
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
+{
+  /* Initial value of 0xFFFF should be 0x1D0F according to
+   * www.joegeluso.com/software/articles/ccitt.htm */
+  u_int16_t crc = 0xFFFF; 
+  int i;
+
+  assert(buffer != NULL);
+
+  for (i = 0; i < len; i++)
+  {
+    crc  = (unsigned char)(crc >> 8) | (crc << 8);
+    crc ^= buffer[i];
+    crc ^= (unsigned char)(crc & 0xff) >> 4;
+    crc ^= (crc << 8) << 4;
+    crc ^= ((crc & 0xff) << 4) << 1;
+  }
+  return crc;
+} /* CalcCrcCcitt */
+#endif
+
+/* -------------------------------------------------------------------------
+ * Function   : GenerateCrc32Table
+ * Description: Generate the table of CRC remainders for all possible bytes,
+ *              according to CRC-32-IEEE 802.3
+ * Input      : none
+ * Output     : none
+ * Return     : none
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
+
+static unsigned long CrcTable[256];
+
+static void GenerateCrc32Table(void)
+{
+  int i, j;
+  u_int32_t crc;
+  for (i = 0; i < 256; i++)
+  {
+    crc = (u_int32_t) i;
+    for (j = 0; j < 8; j++)
+    {
+      if (crc & 1)
+      {
+        crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
+      }
+      else
+      {
+        crc = (crc >> 1);
+      }
+    }
+    CrcTable[i] = crc;
+  } /* for */
+} /* GenerateCrc32Table */
+
+/* -------------------------------------------------------------------------
+ * Function   : CalcCrc32
+ * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3
+ * Input      : buffer - the bytes to calculate the CRC value over
+ *              len - the number of bytes to calculate the CRC value over
+ * Output     : none
+ * Return     : CRC-32 value
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
+{
+  int i, j;
+  u_int32_t crc = 0xffffffffUL;
+  for (i = 0; i < len; i++)
+  {
+    j = ((int) (crc & 0xFF) ^ *buffer++);
+    crc = (crc >> 8) ^ CrcTable[j];
+  }
+  return crc ^ 0xffffffffUL;
+} /* CalcCrc32 */
+
+/* -------------------------------------------------------------------------
+ * Function   : PacketCrc32
+ * Description: Calculates the CRC-32 value for an IP packet
+ * Input      : ipPacket - the IP packet
+ *              len - the number of octets in the IP packet
+ * Output     : none
+ * Return     : 32-bits CRC value
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+u_int32_t PacketCrc32(unsigned char* ipPacket, ssize_t len)
+{
+  struct TSaveTtl sttl;
+  struct ip* ipHeader;
+  u_int32_t result;
+
+  assert(ipPacket != NULL);
+
+  /* Skip TTL: in a multi-homed OLSR-network, the same multicast packet
+   * may enter the network multiple times, each copy differing only in its
+   * TTL value. BMF must not calculate a different CRC for packets that
+   * differ only in TTL. Skip also the IP-header checksum, because it changes
+   * along with TTL. Besides, it is not a good idea to calculate a CRC over
+   * data that already contains a checksum.
+   *
+   * Clip number of bytes over which CRC is calculated to prevent
+   * long packets from possibly claiming too much CPU resources. */
+  assert(len > 0);
+  if (len > CRC_UPTO_NBYTES)
+  {
+    len = CRC_UPTO_NBYTES;
+  }
+
+  SaveTtlAndChecksum(ipPacket, &sttl);
+
+  ipHeader = (struct ip*)ipPacket;
+  ipHeader->ip_ttl = 0xFF; /* fixed value of TTL for CRC-32 calculation */
+  ipHeader->ip_sum = 0x5A5A; /* fixed value of IP header checksum for CRC-32 calculation */
+
+  result = CalcCrc32(ipPacket, len);
+
+  RestoreTtlAndChecksum(ipPacket, &sttl);
+  return result;
+} /* PacketCrc32 */
+
+/* -------------------------------------------------------------------------
+ * Function   : Hash
+ * Description: Calculates a hash value from a 32-bit value
+ * Input      : from32 - 32-bit value
+ * Output     : none
+ * Return     : hash value
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+u_int32_t Hash(u_int32_t from32)
+{
+  return ((from32 >> N_HASH_BITS) + from32) & ((1 << N_HASH_BITS) - 1);
+} /* Hash */
+
+/* -------------------------------------------------------------------------
+ * Function   : InitPacketHistory
+ * Description: Initialize the packet history table and CRC-32 table
+ * Input      : none
+ * Output     : none
+ * Return     : none
+ * Data Used  : PacketHistory
+ * ------------------------------------------------------------------------- */
+void InitPacketHistory(void)
+{
+  int i;
+
+  GenerateCrc32Table();
+
+  for(i = 0; i < HISTORY_HASH_SIZE; i++)
+  {
+    PacketHistory[i] = NULL;
+  }
+} /* InitPacketHistory */
+
+/* -------------------------------------------------------------------------
+ * Function   : CheckAndMarkRecentPacket
+ * Description: Check if this packet was seen recently, then record the fact
+ *              that this packet was seen recently.
+ * Input      : crc32 - 32-bits crc value of the packet
+ * Output     : none
+ * Return     : not recently seen (0), recently seen (1)
+ * Data Used  : PacketHistory
+ * ------------------------------------------------------------------------- */
+int CheckAndMarkRecentPacket(u_int32_t crc32)
+{
+  u_int32_t idx;
+  struct TDupEntry* walker;
+  struct TDupEntry* newEntry;
+
+  idx = Hash(crc32);
+  assert(idx < HISTORY_HASH_SIZE);
+
+  for (walker = PacketHistory[idx]; walker != NULL; walker = walker->next)
+  {
+    if (walker->crc32 == crc32)
+    {
+      /* Found duplicate entry */
+
+      /* Always mark as "seen recently": refresh time-out */
+      walker->timeOut = olsr_getTimestamp(HISTORY_HOLD_TIME);
+
+      return 1;
+    } /* if */
+  } /* for */
+
+  /* No duplicate entry found: create one */
+  newEntry = olsr_malloc(sizeof(struct TDupEntry), "OLSRD P2PD: TDupEntry");
+  if (newEntry != NULL)
+  {
+    newEntry->crc32 = crc32;
+    newEntry->timeOut = olsr_getTimestamp(HISTORY_HOLD_TIME);
+
+    /* Add new entry at the front of the list */
+    newEntry->next = PacketHistory[idx];
+    PacketHistory[idx] = newEntry;
+  }
+
+  return 0;
+} /* CheckAndMarkRecentPacket */
+  
+/* -------------------------------------------------------------------------
+ * Function   : PrunePacketHistory
+ * Description: Prune the packet history table.
+ * Input      : useless - not used
+ * Output     : none
+ * Return     : none
+ * Data Used  : PacketHistory
+ * ------------------------------------------------------------------------- */
+void PrunePacketHistory(void* useless __attribute__ ((unused)))
+{
+  uint i;
+  for (i = 0; i < HISTORY_HASH_SIZE; i++)
+  {
+    if (PacketHistory[i] != NULL)
+    {
+      struct TDupEntry* nextEntry = PacketHistory[i];
+      struct TDupEntry* prevEntry = NULL;
+      while (nextEntry != NULL) 
+      {
+        struct TDupEntry* entry = nextEntry;
+        nextEntry = entry->next;
+
+        if (olsr_isTimedOut(entry->timeOut))
+        {
+          /* De-queue */
+          if (prevEntry != NULL)
+          {
+            prevEntry->next = entry->next;
+          }
+          else
+          {
+            PacketHistory[i] = entry->next;
+          } /* if */
+
+          /* De-allocate memory */
+          free(entry); 
+             }
+             else
+             {
+               prevEntry = entry;
+             } /* if */
+      } /* while */
+    } /* if (PacketHistory[i] != NULL) */
+  } /* for (i = ...) */
+} /* PrunePacketHistory */
index 32cf3a7..3fb8151 100644 (file)
@@ -1,68 +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
+#ifndef _BMF_PACKETHISTORY_H
+#define _BMF_PACKETHISTORY_H
+
+/*
+ * OLSR Basic Multicast Forwarding (BMF) plugin.
+ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
+ * Written by Erik Tromp.
+ * 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 Thales, BMF 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File       : PacketHistory.h
+ * Description: Functions for keeping and accessing the history of processed
+ *              multicast IP packets.
+ * Created    : 29 Jun 2006
+ *
+ * ------------------------------------------------------------------------- */
+
+/* System includes */
+#include <sys/types.h> /* ssize_t */
+#include <sys/times.h> /* clock_t */
+
+#define N_HASH_BITS 15
+#define HISTORY_HASH_SIZE (1 << N_HASH_BITS)
+
+/* Time-out of duplicate entries, in milliseconds */
+#define HISTORY_HOLD_TIME 3000
+
+struct TDupEntry
+{
+  u_int32_t crc32;
+  clock_t timeOut;
+  struct TDupEntry* next;
+};
+
+void InitPacketHistory(void);
+u_int32_t PacketCrc32(unsigned char* ipPkt, ssize_t len);
+u_int32_t Hash(u_int32_t from32);
+void MarkRecentPacket(u_int32_t crc32);
+int CheckAndMarkRecentPacket(u_int32_t crc32);
+void PrunePacketHistory(void*);
+
+#endif /* _BMF_PACKETHISTORY_H */
index 229081e..c133762 100644 (file)
@@ -1,98 +1,98 @@
-#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
+#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);
+}
+
+
index 4be4cc2..64a867d 100644 (file)
@@ -1,22 +1,22 @@
-/* \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
+/* 
+ * 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 */
+
index deb3fb9..737cef8 100644 (file)
-/*\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
-  {.name = "UseHashFilter",.set_plugin_parameter = &SetP2pdUseHashFilter,.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
+/*
+ * 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},
+  {.name = "UseHashFilter",.set_plugin_parameter = &SetP2pdUseHashFilter,.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:
+ */
index 438b69a..5d89b18 100644 (file)
-/*\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 "parser.h"\r
-\r
-/* plugin includes */\r
-#include "NetworkInterfaces.h"  /* NonOlsrInterface,\r
-                                   CreateBmfNetworkInterfaces(),\r
-                                   CloseBmfNetworkInterfaces() */\r
-//#include "Address.h"          /* IsMulticast() */\r
-#include "Packet.h"             /* ENCAP_HDR_LEN,\r
-                                   BMF_ENCAP_TYPE,\r
-                                   BMF_ENCAP_LEN etc. */\r
-#include "PacketHistory.h"\r
-#include "dllist.h"\r
-\r
-int P2pdTtl                        = 0;\r
-int P2pdUseHash                    = 0;  /* Switch off hash filter by default */\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
-char * get_ipv4_str(uint32_t address, char *s, size_t maxlen);\r
-char * get_ipv6_str(unsigned char* address, char *s, size_t maxlen);\r
-void dump_packet(unsigned char* packet, int length);\r
-bool check_and_mark_recent_packet(unsigned char *data, int len);\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 udphdr *udpHeader;\r
-  struct NonOlsrInterface *walker;\r
-  int stripped_len = 0;\r
-  union olsr_ip_addr destAddr;\r
-  int destPort;\r
-  bool isInList = false;\r
-\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
-  if (check_and_mark_recent_packet(encapsulationUdpData, len))\r
-    return;\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 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)\r
-                                                        // + payload_len\r
-      }\r
-\r
-      // Sven-Ola: Don't know how to handle the "stripped_len is uninitialized"\r
-      // 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
-\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
-      if (olsr_cnf->ip_version == AF_INET) {\r
-        // Determine the IP address and the port from the header information\r
-        if (ipHeader->ip_p == SOL_UDP && !IsIpv4Fragment(ipHeader)) {\r
-          udpHeader = (struct udphdr*)(encapsulationUdpData +\r
-                                       GetIpHeaderLength(encapsulationUdpData));\r
-          destAddr.v4.s_addr = ipHeader->ip_dst.s_addr;\r
-          destPort = htons(udpHeader->dest);\r
-          isInList = InUdpDestPortList(AF_INET, &destAddr, destPort);\r
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-          if (!isInList) {\r
-            char tmp[32];\r
-            OLSR_PRINTF(1,\r
-                        "%s: Not in dest/port list: %s:%d\n",\r
-                        PLUGIN_NAME_SHORT,\r
-                        get_ipv4_str(destAddr.v4.s_addr,\r
-                                     tmp,\r
-                                     sizeof(tmp)),\r
-                        destPort);\r
-          }\r
-#endif\r
-        }\r
-      } else /* (olsr_cnf->ip_version == AF_INET6) */ {\r
-        if (ip6Header->ip6_nxt == SOL_UDP && !IsIpv6Fragment(ip6Header)) {\r
-          udpHeader = (struct udphdr*)(encapsulationUdpData + 40);\r
-          memcpy(&destAddr.v6, &ip6Header->ip6_dst, sizeof(struct in6_addr));\r
-          destPort = htons(udpHeader->dest);\r
-          isInList = InUdpDestPortList(AF_INET6, &destAddr, destPort);\r
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-          if (!isInList) {\r
-            char tmp[64];\r
-            OLSR_PRINTF(1,\r
-                        "%s: Not in dest/port list: %s:%d\n",\r
-                        PLUGIN_NAME_SHORT,\r
-                        get_ipv6_str(destAddr.v6.s6_addr,\r
-                                     tmp,\r
-                                     sizeof(tmp)),\r
-                        destPort);\r
-          }\r
-#endif\r
-        }\r
-      }\r
-\r
-      if (!isInList) {\r
-        /* Address/port combination of this packet is not in the UDP dest/port\r
-         * list and will therefore be suppressed. I.e. just continue with the\r
-         * next interface to emit on.\r
-         */\r
-        continue;\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\"",\r
-                   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
- */\r
-int HighestSkfd = -1;\r
-\r
-/* Set of socket file descriptors */\r
-fd_set InputSet;\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : p2pd_message_seen\r
- * Description: Check whether the current message has been seen before\r
- * Input      : head - start of the list to check for the message\r
- *              tail - end of the list to check for the message\r
- *              m    - message to check for in the list\r
- * Output     : none\r
- * Return     : true if message was found, false otherwise\r
- * Data Used  : P2pdDuplicateTimeout\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\r
-                                     // 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
-/* -------------------------------------------------------------------------\r
- * Function   : p2pd_store_message\r
- * Description: Store a new message in the duplicate message check list\r
- * Input      : head - start of the list to add the message to\r
- *              tail - end of the list to add the message to\r
- *              m    - message to add to the list\r
- * Output     : none\r
- * Return     : nothing\r
- * Data Used  : none\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, "%s: Out of memory\n", PLUGIN_NAME_SHORT);\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
-/* -------------------------------------------------------------------------\r
- * Function   : p2pd_is_duplicate_message\r
- * Description: Check whether the specified message is a duplicate\r
- * Input      : msg - message to check for in the list of duplicate messages\r
- * Output     : none\r
- * Return     : true if message was found, false otherwise\r
- * Data Used  : none\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
-/* -------------------------------------------------------------------------\r
- * Function   : olsr_parser\r
- * Description: Function to be passed to the parser engine. This function\r
- *              processes the incoming message and passes it on if necessary.\r
- * Input      : m      - message to parse\r
- *              in_if  - interface to use (unused in this application)\r
- *              ipaddr - IP-address to use (unused in this application)\r
- * Output     : none\r
- * Return     : false if message should be supressed, true otherwise\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-bool\r
-olsr_parser(union olsr_message *m,\r
-            struct interface *in_if __attribute__ ((unused)),\r
-            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
-/* -------------------------------------------------------------------------\r
- * Function   : olsr_p2pd_gen\r
- * Description: Sends a packet in the OLSR network\r
- * Input      : packet - packet to send in the OLSR network\r
- *              len    - length of the packet to send\r
- * Output     : none\r
- * Return     : nothing\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\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 through interfaces */\r
-  for (ifn = ifnet; ifn; ifn = ifn->int_next) {\r
-    //OLSR_PRINTF(1, "%s: Generating packet - [%s]\n", PLUGIN_NAME_SHORT, 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, "%s: could not send on interface: %s\n", PLUGIN_NAME_SHORT, 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
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-      OLSR_PRINTF(1,"%s: NON UDP PACKET\n", PLUGIN_NAME_SHORT);\r
-#endif\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
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-      OLSR_PRINTF(1, "%s: Is IPv4 fragment\n", PLUGIN_NAME_SHORT);\r
-#endif\r
-      return;\r
-    }\r
-\r
-    if (check_and_mark_recent_packet(encapsulationUdpData, nBytes))\r
-      return;\r
-\r
-    udpHeader = (struct udphdr *)(encapsulationUdpData +\r
-                                  GetIpHeaderLength(encapsulationUdpData));\r
-    destPort = ntohs(udpHeader->dest);\r
-\r
-    if (!InUdpDestPortList(AF_INET, &dst, destPort)) {\r
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-      char tmp[32];\r
-      OLSR_PRINTF(1, "%s: Not in dest/port list: %s:%d\n", PLUGIN_NAME_SHORT,\r
-                  get_ipv4_str(dst.v4.s_addr, tmp, sizeof(tmp)), destPort);\r
-#endif\r
-       return;\r
-    }\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,"%s: NON UDP PACKET\n", PLUGIN_NAME_SHORT);\r
-      return;                   /* for */\r
-    }\r
-\r
-    // Check whether this is a IPv6 fragment\r
-    if (IsIpv6Fragment(ipHeader6)) {\r
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-      OLSR_PRINTF(1, "%s: Is IPv6 fragment\n", PLUGIN_NAME_SHORT);\r
-#endif\r
-      return;\r
-    }\r
-\r
-    if (check_and_mark_recent_packet(encapsulationUdpData, nBytes))\r
-      return;\r
-\r
-    udpHeader = (struct udphdr *)(encapsulationUdpData + 40);\r
-    destPort = ntohs(udpHeader->dest);\r
-\r
-    if (!InUdpDestPortList(AF_INET6, &dst, destPort)) {\r
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-      char tmp[64];\r
-      OLSR_PRINTF(1, "%s: Not in dest/port list: %s:%d\n", PLUGIN_NAME_SHORT,\r
-                  get_ipv6_str(dst.v6.s6_addr, tmp, sizeof(tmp)), destPort);\r
-#endif\r
-      return;\r
-    }\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\r
- *              when something is captured\r
- * Input      : none\r
- * Output     : none\r
- * Return     : none\r
- * Data Used  :\r
- * ------------------------------------------------------------------------- */\r
-void\r
-DoP2pd(int skfd,\r
-       void *data __attribute__ ((unused)),\r
-       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,\r
-                      0, (struct sockaddr *)&pktAddr, &addrLen);\r
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-    OLSR_PRINTF(1, "%s: Received %d bytes\n", PLUGIN_NAME_SHORT, nBytes);\r
-#endif\r
-\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_SHORT,\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
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-      OLSR_PRINTF(1, "%s: Multicast or broadcast packet was captured.\n",\r
-                  PLUGIN_NAME_SHORT);\r
-      dump_packet(ipPacket, nBytes);\r
-#endif\r
-      /* A multicast or broadcast packet was captured */\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
-  if (P2pdUseHash) {\r
-    // Initialize hash table for hash based duplicate IP packet check\r
-    InitPacketHistory();\r
-  }\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,\r
-           void *data __attribute__ ((unused)),\r
-           set_plugin_parameter_addon addon __attribute__ ((unused)))\r
-{\r
-  assert(value != NULL);\r
-  P2pdTtl = atoi(value);\r
-\r
-  return 0;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : SetP2pdUseHashFilter\r
- * Description: Set the Hash filter flag for this plug-in\r
- * Input      : value - parameter value to evaluate\r
- *              data  - data associated with this parameter (unused in this app)\r
- *              addon - additional parameter data\r
- * Output     : none\r
- * Return     : Always 0\r
- * Data Used  : P2pdUseHash\r
- * ------------------------------------------------------------------------- */\r
-int\r
-SetP2pdUseHashFilter(const char *value,\r
-                     void *data __attribute__ ((unused)),\r
-                     set_plugin_parameter_addon addon __attribute__ ((unused)))\r
-{\r
-  assert(value != NULL);\r
-  P2pdUseHash = atoi(value);\r
-  \r
-  return 0;\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,\r
-               void *data __attribute__ ((unused)),\r
-               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, "%s: Invalid argument for \"UdpDestPort\"",\r
-                PLUGIN_NAME_SHORT);\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, "%s: Out of memory", PLUGIN_NAME_SHORT);\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,\r
-           &addr6.sin6_addr.s6_addr,\r
-           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
-/* -------------------------------------------------------------------------\r
- * Function   : get_ipv4_str\r
- * Description: Convert the specified address to an IPv4 compatible string\r
- * Input      : address - IPv4 address to convert to string\r
- *              s       - string buffer to contain the resulting string\r
- *              maxlen  - maximum length of the string buffer\r
- * Output     : none\r
- * Return     : Pointer to the string buffer containing the result\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-char *\r
-get_ipv4_str(uint32_t address, char *s, size_t maxlen)\r
-{\r
-  struct sockaddr_in v4;\r
-\r
-  v4.sin_addr.s_addr = address;\r
-  inet_ntop(AF_INET, &v4.sin_addr, s, maxlen);\r
-\r
-  return s;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : get_ipv6_str\r
- * Description: Convert the specified address to an IPv4 compatible string\r
- * Input      : address - IPv6 address to convert to string\r
- *              s       - string buffer to contain the resulting string\r
- *              maxlen  - maximum length of the string buffer\r
- * Output     : none\r
- * Return     : Pointer to the string buffer containing the result\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-char *\r
-get_ipv6_str(unsigned char* address, char *s, size_t maxlen)\r
-{\r
-  struct sockaddr_in6 v6;\r
-\r
-  memcpy(v6.sin6_addr.s6_addr, address, sizeof(v6.sin6_addr.s6_addr));\r
-  inet_ntop(AF_INET6, &v6.sin6_addr, s, maxlen);\r
-\r
-  return s;\r
-}\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : is_broadcast\r
- * Description: Check whether the address represents a broadcast address\r
- * Input      : addr - IPv4 address to check\r
- * Output     : none\r
- * Return     : true if broadcast address, false otherwise\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-bool\r
-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
-/* -------------------------------------------------------------------------\r
- * Function   : is_multicast\r
- * Description: Check whether the address represents a multicast address\r
- * Input      : addr - IPv4 address to check\r
- * Output     : none\r
- * Return     : true if broadcast address, false otherwise\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-bool\r
-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
-#ifdef INCLUDE_DEBUG_OUTPUT\r
-/* -------------------------------------------------------------------------\r
- * Function   : dump_packet\r
- * Description: Dump the specified data as hex output\r
- * Input      : packet - packet to dump to output\r
- *              length - length of the data in the packet\r
- * Output     : none\r
- * Return     : nothing\r
- * Data Used  : none\r
- * ------------------------------------------------------------------------- */\r
-void\r
-dump_packet(unsigned char* packet, int length)\r
-{\r
-  int idx;\r
-\r
-  OLSR_PRINTF(1, "%s: ", PLUGIN_NAME_SHORT);\r
-  for (idx = 0; idx < length; idx++) {\r
-    if (idx > 0 && ((idx % 16) == 0))\r
-      OLSR_PRINTF(1, "\n%s: ", PLUGIN_NAME_SHORT);\r
-    OLSR_PRINTF(1, "%2.2X ", packet[idx]);\r
-  }\r
-  OLSR_PRINTF(1, "\n");\r
-}\r
-#endif\r
-\r
-/* -------------------------------------------------------------------------\r
- * Function   : check_and_mark_recent_packet\r
- * Description: Wrapper function for the Hash based duplicate check\r
- * Input      : data - pointer to a packet of data to be checked\r
- * Output     : none\r
- * Return     : true if duplicate packet, false otherwise\r
- * Data Used  : P2pdUseHash\r
- * ------------------------------------------------------------------------- */\r
-bool\r
-check_and_mark_recent_packet(unsigned char *data,\r
-                             int len __attribute__ ((unused)))\r
-{\r
-  unsigned char * ipPacket;\r
-  uint16_t ipPacketLen;\r
-  uint32_t crc32;\r
-\r
-  /* If we don't use this filter bail out here */\r
-  if (!P2pdUseHash)\r
-    return false;\r
-    \r
-  /* Clean up the hash table each time before we check it */\r
-  PrunePacketHistory(NULL);\r
-\r
-  /* Check for duplicate IP packets now based on a hash */\r
-  ipPacket = GetIpPacket(data);\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 true;\r
-  }\r
-\r
-  return false;\r
-}\r
+/*
+ * 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 "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 "PacketHistory.h"
+#include "dllist.h"
+
+int P2pdTtl                        = 0;
+int P2pdUseHash                    = 0;  /* Switch off hash filter by default */
+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;
+
+clockid_t clockid = CLOCK_MONOTONIC;
+
+bool is_broadcast(const struct sockaddr_in addr);
+bool is_multicast(const struct sockaddr_in addr);
+char * get_ipv4_str(uint32_t address, char *s, size_t maxlen);
+char * get_ipv6_str(unsigned char* address, char *s, size_t maxlen);
+void dump_packet(unsigned char* packet, int length);
+bool check_and_mark_recent_packet(unsigned char *data, int len);
+
+/* -------------------------------------------------------------------------
+ * 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 udphdr *udpHeader;
+  struct NonOlsrInterface *walker;
+  int stripped_len = 0;
+  union olsr_ip_addr destAddr;
+  int destPort;
+  bool isInList = false;
+
+  ipHeader = (struct ip *)encapsulationUdpData;
+  ip6Header = (struct ip6_hdr *)encapsulationUdpData;
+  //OLSR_DEBUG(LOG_PLUGINS, "P2PD PLUGIN got packet from OLSR message\n");
+
+  if (check_and_mark_recent_packet(encapsulationUdpData, len))
+    return;
+
+  /* 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 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) & 0x7F;
+          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];
+        }
+      }
+
+      if (olsr_cnf->ip_version == AF_INET) {
+        // Determine the IP address and the port from the header information
+        if (ipHeader->ip_p == SOL_UDP && !IsIpv4Fragment(ipHeader)) {
+          udpHeader = (struct udphdr*)(encapsulationUdpData +
+                                       GetIpHeaderLength(encapsulationUdpData));
+          destAddr.v4.s_addr = ipHeader->ip_dst.s_addr;
+          destPort = htons(udpHeader->dest);
+          isInList = InUdpDestPortList(AF_INET, &destAddr, destPort);
+#ifdef INCLUDE_DEBUG_OUTPUT
+          if (!isInList) {
+            char tmp[32];
+            OLSR_PRINTF(1,
+                        "%s: Not in dest/port list: %s:%d\n",
+                        PLUGIN_NAME_SHORT,
+                        get_ipv4_str(destAddr.v4.s_addr,
+                                     tmp,
+                                     sizeof(tmp)),
+                        destPort);
+          }
+#endif
+        }
+      } else /* (olsr_cnf->ip_version == AF_INET6) */ {
+        if (ip6Header->ip6_nxt == SOL_UDP && !IsIpv6Fragment(ip6Header)) {
+          udpHeader = (struct udphdr*)(encapsulationUdpData + 40);
+          memcpy(&destAddr.v6, &ip6Header->ip6_dst, sizeof(struct in6_addr));
+          destPort = htons(udpHeader->dest);
+          isInList = InUdpDestPortList(AF_INET6, &destAddr, destPort);
+#ifdef INCLUDE_DEBUG_OUTPUT
+          if (!isInList) {
+            char tmp[64];
+            OLSR_PRINTF(1,
+                        "%s: Not in dest/port list: %s:%d\n",
+                        PLUGIN_NAME_SHORT,
+                        get_ipv6_str(destAddr.v6.s6_addr,
+                                     tmp,
+                                     sizeof(tmp)),
+                        destPort);
+          }
+#endif
+        }
+      }
+
+      if (!isInList) {
+        /* Address/port combination of this packet is not in the UDP dest/port
+         * list and will therefore be suppressed. I.e. just continue with the
+         * next interface to emit on.
+         */
+        continue;
+      }
+      
+      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;
+
+/* -------------------------------------------------------------------------
+ * Function   : p2pd_message_seen
+ * Description: Check whether the current message has been seen before
+ * Input      : head - start of the list to check for the message
+ *              tail - end of the list to check for the message
+ *              m    - message to check for in the list
+ * Output     : none
+ * Return     : true if message was found, false otherwise
+ * Data Used  : P2pdDuplicateTimeout
+ * ------------------------------------------------------------------------- */
+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;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : p2pd_store_message
+ * Description: Store a new message in the duplicate message check list
+ * Input      : head - start of the list to add the message to
+ *              tail - end of the list to add the message to
+ *              m    - message to add to the list
+ * Output     : none
+ * Return     : nothing
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+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, "%s: Out of memory\n", PLUGIN_NAME_SHORT);
+    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);
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : p2pd_is_duplicate_message
+ * Description: Check whether the specified message is a duplicate
+ * Input      : msg - message to check for in the list of duplicate messages
+ * Output     : none
+ * Return     : true if message was found, false otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+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;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : olsr_parser
+ * Description: Function to be passed to the parser engine. This function
+ *              processes the incoming message and passes it on if necessary.
+ * Input      : m      - message to parse
+ *              in_if  - interface to use (unused in this application)
+ *              ipaddr - IP-address to use (unused in this application)
+ * Output     : none
+ * Return     : false if message should be supressed, true otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+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 duplicate messages 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;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : olsr_p2pd_gen
+ * Description: Sends a packet in the OLSR network
+ * Input      : packet - packet to send in the OLSR network
+ *              len    - length of the packet to send
+ * Output     : none
+ * Return     : nothing
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+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 through interfaces */
+  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
+    //OLSR_PRINTF(1, "%s: Generating packet - [%s]\n", PLUGIN_NAME_SHORT, 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, "%s: could not send on interface: %s\n", PLUGIN_NAME_SHORT, 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 */
+#ifdef INCLUDE_DEBUG_OUTPUT
+      OLSR_PRINTF(1,"%s: NON UDP PACKET\n", PLUGIN_NAME_SHORT);
+#endif
+      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)) {
+#ifdef INCLUDE_DEBUG_OUTPUT
+      OLSR_PRINTF(1, "%s: Is IPv4 fragment\n", PLUGIN_NAME_SHORT);
+#endif
+      return;
+    }
+
+    if (check_and_mark_recent_packet(encapsulationUdpData, nBytes))
+      return;
+
+    udpHeader = (struct udphdr *)(encapsulationUdpData +
+                                  GetIpHeaderLength(encapsulationUdpData));
+    destPort = ntohs(udpHeader->dest);
+
+    if (!InUdpDestPortList(AF_INET, &dst, destPort)) {
+#ifdef INCLUDE_DEBUG_OUTPUT
+      char tmp[32];
+      OLSR_PRINTF(1, "%s: Not in dest/port list: %s:%d\n", PLUGIN_NAME_SHORT,
+                  get_ipv4_str(dst.v4.s_addr, tmp, sizeof(tmp)), destPort);
+#endif
+       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,"%s: NON UDP PACKET\n", PLUGIN_NAME_SHORT);
+      return;                   /* for */
+    }
+
+    // Check whether this is a IPv6 fragment
+    if (IsIpv6Fragment(ipHeader6)) {
+#ifdef INCLUDE_DEBUG_OUTPUT
+      OLSR_PRINTF(1, "%s: Is IPv6 fragment\n", PLUGIN_NAME_SHORT);
+#endif
+      return;
+    }
+
+    if (check_and_mark_recent_packet(encapsulationUdpData, nBytes))
+      return;
+
+    udpHeader = (struct udphdr *)(encapsulationUdpData + 40);
+    destPort = ntohs(udpHeader->dest);
+
+    if (!InUdpDestPortList(AF_INET6, &dst, destPort)) {
+#ifdef INCLUDE_DEBUG_OUTPUT
+      char tmp[64];
+      OLSR_PRINTF(1, "%s: Not in dest/port list: %s:%d\n", PLUGIN_NAME_SHORT,
+                  get_ipv6_str(dst.v6.s6_addr, tmp, sizeof(tmp)), destPort);
+#endif
+      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,
+                      0, (struct sockaddr *)&pktAddr, &addrLen);
+#ifdef INCLUDE_DEBUG_OUTPUT
+    OLSR_PRINTF(1, "%s: Received %d bytes\n", PLUGIN_NAME_SHORT, nBytes);
+#endif
+
+    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_SHORT,
+      //              nBytes,
+      //              walker->ifName);
+
+      return;                   /* for */
+    }
+
+    if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
+        pktAddr.sll_pkttype == PACKET_MULTICAST ||
+        pktAddr.sll_pkttype == PACKET_BROADCAST) {
+#ifdef INCLUDE_DEBUG_OUTPUT
+      OLSR_PRINTF(1, "%s: Multicast or broadcast packet was captured.\n",
+                  PLUGIN_NAME_SHORT);
+      dump_packet(ipPacket, nBytes);
+#endif
+      /* 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)
+{
+  if (P2pdUseHash) {
+    // Initialize hash table for hash based duplicate IP packet check
+    InitPacketHistory();
+  }
+
+  //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;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : SetP2pdUseHashFilter
+ * Description: Set the Hash filter flag for this plug-in
+ * Input      : value - parameter value to evaluate
+ *              data  - data associated with this parameter (unused in this app)
+ *              addon - additional parameter data
+ * Output     : none
+ * Return     : Always 0
+ * Data Used  : P2pdUseHash
+ * ------------------------------------------------------------------------- */
+int
+SetP2pdUseHashFilter(const char *value,
+                     void *data __attribute__ ((unused)),
+                     set_plugin_parameter_addon addon __attribute__ ((unused)))
+{
+  assert(value != NULL);
+  P2pdUseHash = atoi(value);
+  
+  return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * 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, "%s: Invalid argument for \"UdpDestPort\"",
+                PLUGIN_NAME_SHORT);
+    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, "%s: Out of memory", PLUGIN_NAME_SHORT);
+    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(addr6.sin6_addr.s6_addr));
+    break;
+  }
+  new->port = destPort;
+  new->next = UdpDestPortList;
+  UdpDestPortList = new;
+
+  // And then we're done
+  return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : get_ipv4_str
+ * Description: Convert the specified address to an IPv4 compatible string
+ * Input      : address - IPv4 address to convert to string
+ *              s       - string buffer to contain the resulting string
+ *              maxlen  - maximum length of the string buffer
+ * Output     : none
+ * Return     : Pointer to the string buffer containing the result
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+char *
+get_ipv4_str(uint32_t address, char *s, size_t maxlen)
+{
+  struct sockaddr_in v4;
+
+  v4.sin_addr.s_addr = address;
+  inet_ntop(AF_INET, &v4.sin_addr, s, maxlen);
+
+  return s;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : get_ipv6_str
+ * Description: Convert the specified address to an IPv4 compatible string
+ * Input      : address - IPv6 address to convert to string
+ *              s       - string buffer to contain the resulting string
+ *              maxlen  - maximum length of the string buffer
+ * Output     : none
+ * Return     : Pointer to the string buffer containing the result
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+char *
+get_ipv6_str(unsigned char* address, char *s, size_t maxlen)
+{
+  struct sockaddr_in6 v6;
+
+  memcpy(v6.sin6_addr.s6_addr, address, sizeof(v6.sin6_addr.s6_addr));
+  inet_ntop(AF_INET6, &v6.sin6_addr, s, maxlen);
+
+  return s;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : is_broadcast
+ * Description: Check whether the address represents a broadcast address
+ * Input      : addr - IPv4 address to check
+ * Output     : none
+ * Return     : true if broadcast address, false otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+bool
+is_broadcast(const struct sockaddr_in addr)
+{
+  if (addr.sin_addr.s_addr == 0xFFFFFFFF)
+    return true;
+
+  return false;
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : is_multicast
+ * Description: Check whether the address represents a multicast address
+ * Input      : addr - IPv4 address to check
+ * Output     : none
+ * Return     : true if broadcast address, false otherwise
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+bool
+is_multicast(const struct sockaddr_in addr)
+{
+  if ((htonl(addr.sin_addr.s_addr) & 0xE0000000) == 0xE0000000)
+    return true;
+
+  return false;
+}
+
+#ifdef INCLUDE_DEBUG_OUTPUT
+/* -------------------------------------------------------------------------
+ * Function   : dump_packet
+ * Description: Dump the specified data as hex output
+ * Input      : packet - packet to dump to output
+ *              length - length of the data in the packet
+ * Output     : none
+ * Return     : nothing
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+void
+dump_packet(unsigned char* packet, int length)
+{
+  int idx;
+
+  OLSR_PRINTF(1, "%s: ", PLUGIN_NAME_SHORT);
+  for (idx = 0; idx < length; idx++) {
+    if (idx > 0 && ((idx % 16) == 0))
+      OLSR_PRINTF(1, "\n%s: ", PLUGIN_NAME_SHORT);
+    OLSR_PRINTF(1, "%2.2X ", packet[idx]);
+  }
+  OLSR_PRINTF(1, "\n");
+}
+#endif
+
+/* -------------------------------------------------------------------------
+ * Function   : check_and_mark_recent_packet
+ * Description: Wrapper function for the Hash based duplicate check
+ * Input      : data - pointer to a packet of data to be checked
+ * Output     : none
+ * Return     : true if duplicate packet, false otherwise
+ * Data Used  : P2pdUseHash
+ * ------------------------------------------------------------------------- */
+bool
+check_and_mark_recent_packet(unsigned char *data,
+                             int len __attribute__ ((unused)))
+{
+  unsigned char * ipPacket;
+  uint16_t ipPacketLen;
+  uint32_t crc32;
+
+  /* If we don't use this filter bail out here */
+  if (!P2pdUseHash)
+    return false;
+    
+  /* Clean up the hash table each time before we check it */
+  PrunePacketHistory(NULL);
+
+  /* Check for duplicate IP packets now based on a hash */
+  ipPacket = GetIpPacket(data);
+  ipPacketLen = GetIpTotalLength(ipPacket);
+
+  /* Calculate packet fingerprint */
+  crc32 = PacketCrc32(ipPacket, ipPacketLen);
+
+  /* Check if this packet was seen recently */
+  if (CheckAndMarkRecentPacket(crc32))
+  {
+    OLSR_PRINTF(
+      8,
+      "%s: --> discarding: packet is duplicate\n",
+      PLUGIN_NAME_SHORT);
+    return true;
+  }
+
+  return false;
+}
index 18ad562..4f90bbf 100644 (file)
-/*\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
-// Either #define or #undef the following line to include extra debugging\r
-#undef INCLUDE_DEBUG_OUTPUT\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
-int SetP2pdTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));\r
-int SetP2pdUseHashFilter(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));\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
+/*
+ * 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
+
+// Either #define or #undef the following line to include extra debugging
+#undef INCLUDE_DEBUG_OUTPUT
+
+#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);
+int SetP2pdTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));
+int SetP2pdUseHashFilter(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)));
+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:
+ */