Adding first version of the OLSR mdns plugin written by Saverio Proto and
authorSaverio Proto <zioproto@gmail.com>
Thu, 26 Mar 2009 00:25:34 +0000 (01:25 +0100)
committerSaverio Proto <zioproto@gmail.com>
Thu, 26 Mar 2009 00:25:34 +0000 (01:25 +0100)
Claudio Pisa (Ninux.org)

13 files changed:
Makefile
lib/mdns/Makefile [new file with mode: 0644]
lib/mdns/README [new file with mode: 0644]
lib/mdns/src/Address.c [new file with mode: 0644]
lib/mdns/src/Address.h [new file with mode: 0644]
lib/mdns/src/NetworkInterfaces.c [new file with mode: 0644]
lib/mdns/src/NetworkInterfaces.h [new file with mode: 0644]
lib/mdns/src/Packet.c [new file with mode: 0644]
lib/mdns/src/Packet.h [new file with mode: 0644]
lib/mdns/src/mdns.c [new file with mode: 0644]
lib/mdns/src/mdns.h [new file with mode: 0644]
lib/mdns/src/olsrd_plugin.c [new file with mode: 0644]
lib/mdns/version-script.txt [new file with mode: 0644]

index ff93b1f..d36c55b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -152,7 +152,7 @@ else
 ifeq ($(OS),win32)
 SUBDIRS := dot_draw httpinfo lq_etx_ff lq_etx_float lq_etx_fpm lq_rfc mini secure txtinfo watchdog
 else
-SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo lq_etx_ff lq_etx_float lq_etx_fpm lq_rfc mini nameservice secure txtinfo watchdog
+SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo lq_etx_ff lq_etx_float lq_etx_fpm lq_rfc mdns mini nameservice secure txtinfo watchdog
 endif
 endif
 
@@ -207,6 +207,10 @@ bmf:
                $(MAKECMD) -C lib/bmf
                $(MAKECMD) -C lib/bmf DESTDIR=$(DESTDIR) install
 
+mdns:
+               $(MAKECMD) -C lib/mdns clean
+               $(MAKECMD) -C lib/mdns
+               $(MAKECMD) -C lib/mdns DESTDIR=$(DESTDIR) install
 quagga:
                $(MAKECMD) -C lib/quagga clean
                $(MAKECMD) -C lib/quagga
diff --git a/lib/mdns/Makefile b/lib/mdns/Makefile
new file mode 100644 (file)
index 0000000..bee4372
--- /dev/null
@@ -0,0 +1,33 @@
+
+OLSRD_PLUGIN = true
+PLUGIN_NAME =  olsrd_mdns
+PLUGIN_VER =   1.0.0
+
+TOPDIR = ../..
+include $(TOPDIR)/Makefile.inc
+
+LIBS +=        $(OS_LIB_PTHREAD)
+
+# Must be specified along with -lpthread on linux
+CPPFLAGS += $(OS_CFLAG_PTHREAD)
+
+ifneq ($(OS),linux)
+
+default_target install clean:
+       @echo "*** mdns Plugin only supported on Linux, sorry!"
+
+else
+
+default_target: $(PLUGIN_FULLNAME)
+
+$(PLUGIN_FULLNAME): $(OBJS) version-script.txt
+               $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
+
+install:       $(PLUGIN_FULLNAME)
+               $(STRIP) $(PLUGIN_FULLNAME)
+               $(INSTALL_LIB)
+
+clean:
+               rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
+
+endif
diff --git a/lib/mdns/README b/lib/mdns/README
new file mode 100644 (file)
index 0000000..7b4eb90
--- /dev/null
@@ -0,0 +1,65 @@
+= OLSR mdns plugin =
+
+This README file is the main documentation source for the OLSR mdns plugin
+
+Last update 24/03/2009
+
+== Description ==
+
+This plugin goal is the distribution of multicast DNS messages over an OLSR Wireless Mesh Network.
+
+In a wireless mesh network, the usage of wireless interfaces in ad-hoc mode and the OLSR routing protocol prevent
+multicast messages to be distributed all over the network. 
+
+We are especially interested in the distribution of Multicast DNS (mDNS) messages, used for host-based service discovery, 
+over the networks that do not directly partecipate in the OLSR mesh cloud.
+
+This task is achieved in the following way: 
+ 1. the local router picks up from the local non-OLSR (HNA) network mDNS messages and encapsulates them in a new type of OLSR messages, 
+ 2. the OLSR infrastructure is exploited for the transport of these messages,
+ 3. remote routers decapsulate mDNS messages from received OLSR messages and send them over their attached non-OLSR networks.
+
+The work could have its practical and immediate application in all the wireless network communities that employ the OLSR protocol.
+
+The plugin captures the traffic (only IPv4 if OLSR is running IPv4 and only IPv6 if OLSR is running IPv6)
+and encapsulates this traffic in OLSR messages that are forwarded to all the other nodes in the mesh.
+
+Other nodes running the plugin will decapsulate the packets and will send them to the interfaces specified in the configuration file
+
+Let's get this example topology
+
+pc1->eth0 ----- eth0<-r1->ath0 -------ath0<-r2->eth0 ---------eth0<-pc2
+
+r1 and r2 are OLSR routers with mdns plugin enabled. pc1 will be able to receive mdns traffic generated at pc2 and vice versa
+
+The most interesting feature is that messages are forwarded also by OLSR routers without the plugin. For example:
+
+pc1->eth0 ----- eth0<-r1->ath0 ---r3----ath0<-r2->eth0 ---------eth0<-pc2
+
+also in this topology mdns traffic between pc1 and pc2 is possible because r3 forwards mdns plugin OLSR packets even if it is not aware of the new application.
+
+== Configuration ==
+
+To enable the Plugin use the following syntax
+
+LoadPlugin "olsrd_mdns.so.1.0.0"
+{
+PlParam     "NonOlsrIf"  "eth0"
+PlParam     "NonOlsrIf"  "eth1"
+}
+
+Where eth0 and eth1 are the names of the interfaces where you want to capture traffic (and decapsulate incoming traffic).
+
+Note that this interfaces must not talk OLSR and also the subnets on this interfaces must be announced with an appropriate HNA entry.
+This version of the plugin will not chech this stuff to be properly configured!
+
+
+
+=== References ===
+
+ * Multicast DNS: [http://tools.ietf.org/html/draft-cheshire-dnsext-multicastdns-07 IETF draft-cheshire-dnsext-multicastdns-07]
+ * OLSR Optimized Link State Routing: [http://tools.ietf.org/html/rfc3626 IETF RFC 3626]
+
+=== Contact ===
+ * Saverio Proto proto@ing.uniroma2.it
+ * Claudio Pisa claudio.pisa@clauz.net
diff --git a/lib/mdns/src/Address.c b/lib/mdns/src/Address.c
new file mode 100644 (file)
index 0000000..3e02075
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#include "Address.h"
+
+/* System includes */
+#include <stddef.h> /* NULL */
+#include <string.h> /* strcmp */
+#include <assert.h> /* assert() */
+#include <netinet/ip.h> /* struct ip */
+#include <netinet/udp.h> /* struct udphdr */
+
+/* OLSRD includes */
+#include "defs.h" /* ipequal */
+#include "olsr_protocol.h" /* OLSRPORT */
+
+/* Plugin includes */
+#include "mdns.h" /* BMF_ENCAP_PORT */
+#include "NetworkInterfaces.h" /* TBmfInterface */
+
+/* Whether or not to flood local broadcast packets (e.g. packets with IP
+ * destination 192.168.1.255). May be overruled by setting the plugin
+ * parameter "DoLocalBroadcast" to "no" */
+//int EnableLocalBroadcast = 1;
+
+/* -------------------------------------------------------------------------
+ * Function   : IsMulticast
+ * Description: Check if an IP address is a multicast address
+ * Input      : ipAddress
+ * Output     : none
+ * Return     : true (1) or false (0)
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+int IsMulticast(union olsr_ip_addr* ipAddress)
+{
+  assert(ipAddress != NULL);
+
+  return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
+}
+
diff --git a/lib/mdns/src/Address.h b/lib/mdns/src/Address.h
new file mode 100644 (file)
index 0000000..5460259
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#ifndef _MDNS_ADDRESS_H
+#define _MDNS_ADDRESS_H
+
+#include "olsr_types.h" /* olsr_ip_addr */
+#include "plugin.h"     /* union set_plugin_parameter_addon */
+#include "interfaces.h" /* struct interface */
+
+struct TBmfInterface;
+
+int IsMulticast(union olsr_ip_addr* ipAddress);
+
+#endif /* _MDNS_ADDRESS_H */
+
diff --git a/lib/mdns/src/NetworkInterfaces.c b/lib/mdns/src/NetworkInterfaces.c
new file mode 100644 (file)
index 0000000..bffb6f8
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#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 "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
+#include "Address.h" /* IsMulticast() */
+
+/* List of network interface objects used by BMF plugin */
+struct TBmfInterface* BmfInterfaces = NULL;
+struct TBmfInterface* LastBmfInterface = NULL;
+
+/* 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   : 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
+ * ------------------------------------------------------------------------- */
+static 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)
+  {
+    BmfPError("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)
+  {
+    BmfPError("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)
+  {
+    BmfPError("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)
+  {
+    BmfPError("bind() error");
+    close(skfd);
+    return -1;
+  }
+
+  /* Set socket to blocking operation */
+  if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
+  {
+    BmfPError("fcntl() error");
+    close(skfd);
+    return -1;
+  }
+
+  //AddDescriptorToInputSet(skfd);
+  add_olsr_socket(skfd,&DoMDNS,NULL,NULL,SP_PR_READ);
+
+  return skfd;
+} /* CreateCaptureSocket */
+
+/* -------------------------------------------------------------------------
+ * Function   : CreateInterface
+ * Description: Create a new TBmfInterface object and adds it to the global
+ *              BmfInterfaces 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  : BmfInterfaces, LastBmfInterface
+ * ------------------------------------------------------------------------- */
+
+//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 TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
+
+  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)
+  {
+    BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
+    close(capturingSkfd);
+    close(encapsulatingSkfd);
+    free(newIf);
+    return 0;
+  }
+
+  /* Copy data into TBmfInterface 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)
+    {
+      BmfPError("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)
+    {
+      BmfPError("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->nBmfPacketsRx = 0;
+  //newIf->nBmfPacketsRxDup = 0;
+  //newIf->nBmfPacketsTx = 0;
+
+  /* Add new TBmfInterface object to global list. OLSR interfaces are
+   * added at the front of the list, non-OLSR interfaces at the back. */
+  if (BmfInterfaces == NULL)
+  {
+    /* First TBmfInterface object in list */
+    BmfInterfaces = newIf;
+    LastBmfInterface = newIf;
+  }
+  else if (olsrIntf != NULL)
+  {
+    /* Add new TBmfInterface object at front of list */
+    newIf->next = BmfInterfaces;
+    BmfInterfaces = newIf;
+  }
+  else
+  {
+    /* Add new TBmfInterface object at back of list */
+    newIf->next = NULL;
+    LastBmfInterface->next= newIf;
+    LastBmfInterface = 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   : CreateBmfNetworkInterfaces
+ * Description: Create a list of TBmfInterface 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 CreateBmfNetworkInterfaces(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)
+  {
+    BmfPError("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)
+    {
+      BmfPError("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 && ! IsNonOlsrBmfIf(ifr->ifr_name))
+    {
+      /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
+       * interface in the BMF plugin parameter list */
+      continue; /* for (n = ...) */
+    }
+       
+    if (! IsNonOlsrBmfIf(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 (BmfInterfaces == 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;
+} /* CreateBmfNetworkInterfaces */
+
+/* -------------------------------------------------------------------------
+ * 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   : CloseBmfNetworkInterfaces
+ * 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 CloseBmfNetworkInterfaces(void)
+{
+  int nClosed = 0;
+  u_int32_t totalOlsrBmfPacketsRx = 0;
+  u_int32_t totalOlsrBmfPacketsRxDup = 0;
+  u_int32_t totalOlsrBmfPacketsTx = 0;
+  u_int32_t totalNonOlsrBmfPacketsRx = 0;
+  u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
+  u_int32_t totalNonOlsrBmfPacketsTx = 0;
+
+  /* Close all opened sockets */
+  struct TBmfInterface* nextBmfIf = BmfInterfaces;
+  while (nextBmfIf != NULL)
+  {
+    struct TBmfInterface* bmfIf = nextBmfIf;
+    nextBmfIf = bmfIf->next;
+
+    if (bmfIf->capturingSkfd >= 0)
+    {
+      close(bmfIf->capturingSkfd);
+      nClosed++;
+    }
+    if (bmfIf->encapsulatingSkfd >= 0)
+    {
+      close(bmfIf->encapsulatingSkfd);
+      nClosed++;
+    }
+
+    //OLSR_PRINTF(
+    //  7,
+    //  "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
+    //  PLUGIN_NAME_SHORT,
+    //  bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
+    //  bmfIf->ifName,
+    //  bmfIf->nBmfPacketsRx,
+    //  bmfIf->nBmfPacketsRxDup,
+    //  bmfIf->nBmfPacketsTx);
+
+    //OLSR_PRINTF(
+    //  1,
+    //  "%s: closed %s interface \"%s\"\n",
+    //  PLUGIN_NAME_SHORT,
+    //  bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
+    //  bmfIf->ifName);
+
+    /* Add totals */
+    if (bmfIf->olsrIntf != NULL)
+    {
+      totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
+      totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
+      totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
+    }
+    else
+    {
+      totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
+      totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
+      totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
+    }
+
+    free(bmfIf);
+  } /* while */
+
+  BmfInterfaces = NULL;
+
+  //OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
+
+} /* CloseBmfNetworkInterfaces */
+
+#define MAX_NON_OLSR_IFS 32
+static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
+static int nNonOlsrIfs = 0;
+
+/* -------------------------------------------------------------------------
+ * Function   : AddNonOlsrBmfIf
+ * 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 AddNonOlsrBmfIf(
+  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;
+  }
+
+  strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
+  NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
+  nNonOlsrIfs++;
+  return 0;
+} /* AddNonOlsrBmfIf */
+
+/* -------------------------------------------------------------------------
+ * Function   : IsNonOlsrBmfIf
+ * 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 IsNonOlsrBmfIf(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;
+} /* IsNonOlsrBmfIf */
+
+
diff --git a/lib/mdns/src/NetworkInterfaces.h b/lib/mdns/src/NetworkInterfaces.h
new file mode 100644 (file)
index 0000000..7340c70
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#ifndef _BMF_NETWORKINTERFACES_H
+#define _BMF_NETWORKINTERFACES_H
+
+/* System includes */
+#include <netinet/in.h> /* struct in_addr */
+
+/* OLSR includes */
+#include "olsr_types.h" /* olsr_ip_addr */
+#include "plugin.h" /* union set_plugin_parameter_addon */
+
+/* Plugin includes */
+#include "Packet.h" /* IFHWADDRLEN */
+#include "mdns.h"
+/* Size of buffer in which packets are received */
+#define BMF_BUFFER_SIZE 2048
+
+struct TBmfInterface
+{
+  /* 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 "BmfMechanism" 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 nBmfPacketsRx;
+  u_int32_t nBmfPacketsRxDup;
+  u_int32_t nBmfPacketsTx;
+
+  /* Next element in list */
+  struct TBmfInterface* next;
+};
+
+extern struct TBmfInterface* BmfInterfaces;
+
+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 TBmfMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
+extern enum TBmfMechanism BmfMechanism;
+
+int SetBmfInterfaceName(const char* ifname, void* data, set_plugin_parameter_addon addon);
+int SetBmfInterfaceIp(const char* ip, void* data, set_plugin_parameter_addon addon);
+int SetCapturePacketsOnOlsrInterfaces(const char* enable, void* data, set_plugin_parameter_addon addon);
+int SetBmfMechanism(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 TBmfInterface* intf,
+  union olsr_ip_addr* source,
+  union olsr_ip_addr* forwardedBy,
+  union olsr_ip_addr* forwardedTo,
+  int* nPossibleNeighbors);
+
+int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
+void AddInterface(struct interface* newIntf);
+void CloseBmfNetworkInterfaces(void);
+int AddNonOlsrBmfIf(const char* ifName, void* data, set_plugin_parameter_addon addon);
+int IsNonOlsrBmfIf(const char* ifName);
+void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr);
+void AddMulticastRoute(void);
+void DeleteMulticastRoute(void);
+
+#endif /* _BMF_NETWORKINTERFACES_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib/mdns/src/Packet.c b/lib/mdns/src/Packet.c
new file mode 100644 (file)
index 0000000..29449af
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+#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   : 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   : 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 */
+
+/* -------------------------------------------------------------------------
+ * Function   : GetIpHeader
+ * Description: Retrieve the IP header from BMF encapsulation UDP data
+ * Input      : encapsulationUdpData - the encapsulation UDP data
+ * Output     : none
+ * Return     : IP header
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
+{
+  return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
+} /* GetIpHeader */
+
+/* -------------------------------------------------------------------------
+ * Function   : GetIpPacket
+ * Description: Retrieve the IP packet from BMF encapsulation UDP data
+ * Input      : encapsulationUdpData - the encapsulation UDP data
+ * Output     : none
+ * Return     : The IP packet
+ * Data Used  : none
+ * ------------------------------------------------------------------------- */
+unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
+{
+  return encapsulationUdpData + ENCAP_HDR_LEN;
+} /* GetIpPacket */
+
+
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib/mdns/src/Packet.h b/lib/mdns/src/Packet.h
new file mode 100644 (file)
index 0000000..2ce069d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#ifndef _MDNS_PACKET_H
+#define _MDNS_PACKET_H
+
+
+/* System includes */
+#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
+#include <sys/types.h> /* u_int8_t, u_int16_t */
+
+/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
+ * with a 8-bytes BMF 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))
+#define BMF_ENCAP_TYPE 1
+#define BMF_ENCAP_LEN 6
+
+struct TSaveTtl
+{
+  u_int8_t ttl;
+  u_int16_t check;
+} __attribute__((__packed__));
+
+int IsIpFragment(unsigned char* ipPacket);
+u_int16_t GetIpTotalLength(unsigned char* ipPacket);
+unsigned int GetIpHeaderLength(unsigned char* ipPacket);
+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);
+struct ip* GetIpHeader(unsigned char* encapsulationUdpData);
+unsigned char* GetIpPacket(unsigned char* encapsulationUdpData);
+
+#endif /* _MDNS_PACKET_H */
+       
diff --git a/lib/mdns/src/mdns.c b/lib/mdns/src/mdns.c
new file mode 100644 (file)
index 0000000..22c7630
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#include "mdns.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 <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>
+
+/* 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 "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
+#include "link_set.h" /* get_best_link_to_neighbor() */
+#include "net_olsr.h" /* ipequal */
+
+/* plugin includes */
+#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
+#include "Address.h" /* IsMulticast() */
+#include "Packet.h" /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
+
+
+/* -------------------------------------------------------------------------
+ * 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 */
+  union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
+  union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
+  struct TBmfInterface* walker;
+  ipHeader = (struct ip*) encapsulationUdpData;
+  mcSrc.v4 = ipHeader->ip_src;
+  mcDst.v4 = ipHeader->ip_dst;
+
+  //OLSR_PRINTF(3, "MDNS PLUGIN got packet from OLSR message\n");
+
+
+  /* Check with each network interface what needs to be done on it */
+  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
+  {
+    /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
+    if (walker->olsrIntf == NULL)
+    {
+      int nBytesWritten;
+      struct sockaddr_ll dest;
+
+      memset(&dest, 0, sizeof(dest));
+      dest.sll_family = AF_PACKET;
+      if ((encapsulationUdpData[0] & 0xf0) == 0x40) dest.sll_protocol = htons(ETH_P_IP);
+      if ((encapsulationUdpData[0] & 0xf0) == 0x60) dest.sll_protocol = htons(ETH_P_IPV6);
+      //TODO: if packet is not IP die here
+      dest.sll_ifindex = if_nametoindex(walker->ifName);
+      dest.sll_halen = IFHWADDRLEN;
+
+      /* 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. */
+      memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
+
+      nBytesWritten = sendto(
+        walker->capturingSkfd,
+        encapsulationUdpData,
+        len,
+        0,
+        (struct sockaddr*) &dest,
+        sizeof(dest));
+      if (nBytesWritten != len)
+      {
+        BmfPError("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 */
+
+
+
+bool
+olsr_parser(union olsr_message *m,
+            struct interface *in_if __attribute__((unused)),
+            union olsr_ip_addr *ipaddr)
+{
+        union olsr_ip_addr originator;
+        int size;
+        olsr_reltime vtime;
+        //OLSR_PRINTF(2, "MDNS 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(olsr_ipcmp(&originator, &olsr_cnf->router_id) == 0)
+                return false;
+
+        /* Check that the neighbor this message was received from is symmetric.
+ *         If not - back off*/
+        if(check_neighbor_link(ipaddr) != SYM_LINK) {
+                //struct ipaddr_str strbuf;
+                //OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
+                return false;
+        }    
+       
+        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);
+       }
+        /* Forward the message */
+        return true;
+}
+
+//Sends a packet in the OLSR network
+void
+olsr_mdns_gen(unsigned char* packet, int len)
+{
+        /* send buffer: huge */
+        char buffer[10240];
+        union olsr_message *message = (union olsr_message *)buffer;
+        struct interface *ifn;
+        //int namesize;
+
+        /* fill message */
+        if(olsr_cnf->ip_version == AF_INET)
+        {    
+                /* IPv4 */
+                message->v4.olsr_msgtype = MESSAGE_TYPE;
+                message->v4.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
+                memcpy(&message->v4.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
+                message->v4.ttl = MAX_TTL;
+                message->v4.hopcnt = 0; 
+                message->v4.seqno = htons(get_msg_seqno());
+
+                message->v4.olsr_msgsize = htons(len+12);
+
+               memcpy(&message->v4.message,packet,len);
+                len=len+12;
+        }    
+        else 
+        {    
+                /* IPv6 */
+                message->v6.olsr_msgtype = MESSAGE_TYPE;
+                message->v6.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
+                memcpy(&message->v6.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
+                message->v6.ttl = MAX_TTL;
+                message->v6.hopcnt = 0; 
+                message->v6.seqno = htons(get_msg_seqno());
+
+                message->v6.olsr_msgsize = htons(len+12+96);
+               memcpy(&message->v6.message,packet,len);
+                len=len+12+96;
+        }    
+
+        /* looping trough interfaces */
+        OLSR_FOR_ALL_INTERFACES(ifn) {
+                //OLSR_PRINTF(1, "MDNS PLUGIN: Generating packet - [%s]\n", ifn->int_name);
+
+                if(net_outbuffer_push(ifn, message, len) != len) {
+                        /* send data and try again */
+                        net_output(ifn);
+                        if(net_outbuffer_push(ifn, message, len) != len) {
+                                //OLSR_PRINTF(1, "MDNS PLUGIN: could not send on interface: %s\n", ifn->int_name);
+                        }    
+                }    
+        } OLSR_FOR_ALL_INTERFACES_END(ifn);
+}
+
+/* -------------------------------------------------------------------------
+ * Function   : BmfPError
+ * 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 BmfPError(const char* format, ...)
+{
+#define MAX_STR_DESC 255
+#ifndef NODEBUG
+  //char* strErr = strerror(errno);
+#endif
+  char strDesc[MAX_STR_DESC];
+
+  /* Rely on short-circuit boolean evaluation */
+  if (format == NULL || *format == '\0')
+  {
+    //OLSR_PRINTF(1, "%s: %s\n", PLUGIN_NAME, strErr);
+  }
+  else
+  {
+    va_list arglist;
+
+    //OLSR_PRINTF(1, "%s: ", PLUGIN_NAME);
+
+    va_start(arglist, format);
+    vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
+    va_end(arglist);
+
+    strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
+
+    //OLSR_PRINTF(1, "%s: %s\n", strDesc, strErr);
+  }
+} /* BmfPError */
+
+/* -------------------------------------------------------------------------
+ * 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 = olsr_lookup_main_addr_by_alias(ip);
+  if (result == NULL)
+  {
+    result = ip;
+  }
+  return result;
+} /* MainAddressOf */
+
+
+/* -------------------------------------------------------------------------
+ * Function   : BmfPacketCaptured
+ * Description: Handle a captured IP packet
+ * Input      : intf - the network interface on which the packet was captured
+ *              sllPkttype - the type of packet. Either PACKET_OUTGOING,
+ *                PACKET_BROADCAST or PACKET_MULTICAST.
+ *              encapsulationUdpData - space for the encapsulation header, followed by
+ *                the captured IP packet
+ * Output     : none
+ * Return     : none
+ * Data Used  : BmfInterfaces
+ * Notes      : The IP packet is assumed to be captured on a socket of family
+ *              PF_PACKET and type SOCK_DGRAM (cooked).
+ * ------------------------------------------------------------------------- */
+static void BmfPacketCaptured(
+  //struct TBmfInterface* intf,
+  //unsigned char sllPkttype,
+  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;
+
+            /* Only forward multicast packets. If configured, also forward local broadcast packets */
+            if (IsMulticast(&dst))
+            {
+              /* continue */
+            }
+            else
+            {
+              return;
+            }
+            if (ipHeader->ip_p != SOL_UDP)
+            {
+              /* Not UDP */
+              //OLSR_PRINTF(1,"NON UDP PACKET\n");
+              return; /* for */
+            }
+            udpHeader = (struct udphdr*)(encapsulationUdpData + GetIpHeaderLength(encapsulationUdpData));
+            destPort = ntohs(udpHeader->dest);
+            if (destPort != 5353)
+            {
+               return; 
+            }
+  }//END IPV4
+
+  else if ((encapsulationUdpData[0] & 0xf0) == 0x60) { //IPv6
+  
+            ipHeader6 = (struct ip6_hdr*) encapsulationUdpData;
+            if (ipHeader6->ip6_dst.s6_addr[0] == 0xff) //Multicast
+            {
+              //Continua
+            }
+            else
+            {
+            return; //not multicast
+            }
+            if (ipHeader6->ip6_nxt != SOL_UDP)
+            {
+              /* Not UDP */
+              //OLSR_PRINTF(1,"NON UDP PACKET\n");
+              return; /* for */
+            }
+            udpHeader = (struct udphdr*)(encapsulationUdpData + 40);
+            destPort = ntohs(udpHeader->dest);
+            if (destPort != 5353)
+            {
+               return; 
+            }
+  } //END IPV6
+  else return; //Is not IP packet
+
+  /* Check if the frame is captured on an OLSR-enabled interface */
+  //isFromOlsrIntf = (intf->olsrIntf != NULL); TODO: put again this check
+
+
+  /* Lookup main address of source in the MID table of OLSR */
+  origIp = MainAddressOf(&src);
+
+  // send the packet to OLSR forward mechanism
+  olsr_mdns_gen(encapsulationUdpData,nBytes);
+} /* BmfPacketCaptured */
+
+
+/* -------------------------------------------------------------------------
+ * Function   : DoMDNS
+ * Description: This function is registered with the OLSR scheduler and called when something is captured
+ * Input      : none
+ * Output     : none
+ * Return     : none
+ * Data Used  : 
+ * ------------------------------------------------------------------------- */
+void DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
+
+{
+  unsigned char rxBuffer[BMF_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,
+                       BMF_BUFFER_SIZE, //TODO: understand how to change this
+                       0,
+                       (struct sockaddr*)&pktAddr,
+                       &addrLen);
+       if (nBytes < 0)
+       {
+
+               return; /* for */
+       } /* if (nBytes < 0) */
+
+       /* Check if the number of received bytes is large enough for an IP
+        * packet which contains at least a minimum-size IP header.
+        * Note: There is an apparent bug in the packet socket implementation in
+        * combination with VLAN interfaces. On a VLAN interface, the value returned
+        * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
+        * returned on a non-VLAN interface, for the same ethernet frame. */
+       if (nBytes < (int)sizeof(struct ip))
+       {
+               ////OLSR_PRINTF(
+               //              1,
+               //              "%s: captured frame too short (%d bytes) on \"%s\"\n",
+               //              PLUGIN_NAME,
+               //              nBytes,
+               //              walker->ifName);
+
+               return; /* for */
+       }
+
+       if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
+                       pktAddr.sll_pkttype == PACKET_MULTICAST ||
+                       pktAddr.sll_pkttype == PACKET_BROADCAST)
+       {
+               /* A multicast or broadcast packet was captured */
+
+               ////OLSR_PRINTF(
+               //              1,
+               //              "%s: captured frame (%d bytes) on \"%s\"\n",
+               //              PLUGIN_NAME,
+               //              nBytes,
+               //              walker->ifName);
+               //BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);
+               BmfPacketCaptured(ipPacket,nBytes);
+
+        } /* if (pktAddr.sll_pkttype == ...) */
+      } /* if (skfd >= 0 && (FD_ISSET...)) */
+} /* DoMDNS */
+
+int InitMDNS(struct interface* skipThisIntf)
+{
+  
+
+  //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
+  olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
+  //Creates captures sockets and register them to the OLSR scheduler
+  CreateBmfNetworkInterfaces(skipThisIntf);
+
+  return 0;
+} /* InitMDNS */
+
+/* -------------------------------------------------------------------------
+ * Function   : CloseMDNS
+ * Description: Close the MDNS plugin and clean up
+ * Input      : none
+ * Output     : none
+ * Return     : none
+ * Data Used  : 
+ * ------------------------------------------------------------------------- */
+void CloseMDNS(void)
+{
+  CloseBmfNetworkInterfaces();
+} 
+
diff --git a/lib/mdns/src/mdns.h b/lib/mdns/src/mdns.h
new file mode 100644 (file)
index 0000000..a8c3a55
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+
+#ifndef _MDNS_MDNS_H
+#define _MDNS_MDNS_H
+
+
+#include "plugin.h" /* union set_plugin_parameter_addon */
+
+#include "parser.h"
+
+#define MESSAGE_TYPE 132
+#define PARSER_TYPE            MESSAGE_TYPE
+#define EMISSION_INTERVAL       10     /* seconds */
+#define EMISSION_JITTER         25      /* percent */
+#define MDNS_VALID_TIME          1800    /* seconds */
+
+/* BMF plugin data */
+#define PLUGIN_NAME "OLSRD MDNS plugin"
+#define PLUGIN_NAME_SHORT "OLSRD MDNS"
+#define PLUGIN_VERSION "1.0.0 (" __DATE__ " " __TIME__ ")"
+#define PLUGIN_COPYRIGHT "  (C) Ninux.org"
+#define PLUGIN_AUTHOR "  Saverio Proto (zioproto@gmail.com)"
+#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
+#define PLUGIN_INTERFACE_VERSION 5
+
+/* UDP-Port on which multicast packets are encapsulated */
+//#define BMF_ENCAP_PORT 50698
+
+/* Forward declaration of OLSR interface type */
+struct interface;
+
+//extern int FanOutLimit;
+//extern int BroadcastRetransmitCount;
+
+void DoMDNS(int sd, void * x, unsigned int y);
+void BmfPError(const char* format, ...) __attribute__((format(printf, 1, 2)));
+union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip);
+//int InterfaceChange(struct interface* interf, int action);
+//int SetFanOutLimit(const char* value, void* data, set_plugin_parameter_addon addon);
+//int InitBmf(struct interface* skipThisIntf);
+//void CloseBmf(void);
+int InitMDNS(struct interface* skipThisIntf);
+void CloseMDNS(void);
+
+void olsr_mdns_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 /* _MDNS_MDNS_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/lib/mdns/src/olsrd_plugin.c b/lib/mdns/src/olsrd_plugin.c
new file mode 100644 (file)
index 0000000..6b53313
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+OLSR MDNS plugin.
+Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
+
+    This file is part of OLSR MDNS PLUGIN.
+
+    The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+
+/* System includes */
+#include <assert.h> /* assert() */
+#include <stddef.h> /* NULL */
+
+/* OLSRD includes */
+#include "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() */
+
+/* BMF includes */
+#include "mdns.h" /* InitBmf(), CloseBmf() */
+#include "NetworkInterfaces.h" /* AddNonOlsrBmfIf(), SetBmfInterfaceIp(), ... */
+#include "Address.h" /* DoLocalBroadcast() */
+
+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     : BMF 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)
+{
+  /* Clear the packet history */
+  //InitPacketHistory();
+
+  /* Register ifchange function */
+  //add_ifchgf(&InterfaceChange);
+
+  /* create the cookie */
+  //prune_packet_history_timer_cookie = olsr_alloc_cookie("BMF: Prune Packet History", OLSR_COOKIE_TYPE_TIMER);
+
+  /* Register the duplicate registration pruning process */
+  //olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+  //                 &PrunePacketHistory, NULL, prune_packet_history_timer_cookie->ci_id);
+
+
+  return InitMDNS(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)
+{
+  CloseMDNS();
+}
+
+static const struct olsrd_plugin_parameters plugin_parameters[] = {
+    { .name = "NonOlsrIf", .set_plugin_parameter = &AddNonOlsrBmfIf, .data = NULL },
+    //{ .name = "DoLocalBroadcast", .set_plugin_parameter = &DoLocalBroadcast, .data = NULL },
+    //{ .name = "BmfInterface", .set_plugin_parameter = &SetBmfInterfaceName, .data = NULL },
+    //{ .name = "BmfInterfaceIp", .set_plugin_parameter = &SetBmfInterfaceIp, .data = NULL },
+    //{ .name = "CapturePacketsOnOlsrInterfaces", .set_plugin_parameter = &SetCapturePacketsOnOlsrInterfaces, .data = NULL },
+    //{ .name = "BmfMechanism", .set_plugin_parameter = &SetBmfMechanism, .data = NULL },
+    //{ .name = "FanOutLimit", .set_plugin_parameter = &SetFanOutLimit, .data = NULL },
+    //{ .name = "BroadcastRetransmitCount", .set_plugin_parameter = &set_plugin_int, .data = &BroadcastRetransmitCount},
+};
+
+/* -------------------------------------------------------------------------
+ * 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:
+ */
diff --git a/lib/mdns/version-script.txt b/lib/mdns/version-script.txt
new file mode 100644 (file)
index 0000000..a145659
--- /dev/null
@@ -0,0 +1,10 @@
+VERS_1.0
+{
+  global:
+    olsrd_plugin_interface_version;
+    olsrd_plugin_init;
+    olsrd_get_plugin_parameters;
+
+  local:
+    *;
+};