1.1 --- a/Makefile Wed Mar 25 20:53:33 2009 +0100
1.2 +++ b/Makefile Thu Mar 26 01:25:34 2009 +0100
1.3 @@ -152,7 +152,7 @@ else
1.4 ifeq ($(OS),win32)
1.5 SUBDIRS := dot_draw httpinfo lq_etx_ff lq_etx_float lq_etx_fpm lq_rfc mini secure txtinfo watchdog
1.6 else
1.7 -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
1.8 +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
1.9 endif
1.10 endif
1.11
1.12 @@ -207,6 +207,10 @@ bmf:
1.13 $(MAKECMD) -C lib/bmf
1.14 $(MAKECMD) -C lib/bmf DESTDIR=$(DESTDIR) install
1.15
1.16 +mdns:
1.17 + $(MAKECMD) -C lib/mdns clean
1.18 + $(MAKECMD) -C lib/mdns
1.19 + $(MAKECMD) -C lib/mdns DESTDIR=$(DESTDIR) install
1.20 quagga:
1.21 $(MAKECMD) -C lib/quagga clean
1.22 $(MAKECMD) -C lib/quagga
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/lib/mdns/Makefile Thu Mar 26 01:25:34 2009 +0100
2.3 @@ -0,0 +1,33 @@
2.4 +
2.5 +OLSRD_PLUGIN = true
2.6 +PLUGIN_NAME = olsrd_mdns
2.7 +PLUGIN_VER = 1.0.0
2.8 +
2.9 +TOPDIR = ../..
2.10 +include $(TOPDIR)/Makefile.inc
2.11 +
2.12 +LIBS += $(OS_LIB_PTHREAD)
2.13 +
2.14 +# Must be specified along with -lpthread on linux
2.15 +CPPFLAGS += $(OS_CFLAG_PTHREAD)
2.16 +
2.17 +ifneq ($(OS),linux)
2.18 +
2.19 +default_target install clean:
2.20 + @echo "*** mdns Plugin only supported on Linux, sorry!"
2.21 +
2.22 +else
2.23 +
2.24 +default_target: $(PLUGIN_FULLNAME)
2.25 +
2.26 +$(PLUGIN_FULLNAME): $(OBJS) version-script.txt
2.27 + $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
2.28 +
2.29 +install: $(PLUGIN_FULLNAME)
2.30 + $(STRIP) $(PLUGIN_FULLNAME)
2.31 + $(INSTALL_LIB)
2.32 +
2.33 +clean:
2.34 + rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
2.35 +
2.36 +endif
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/lib/mdns/README Thu Mar 26 01:25:34 2009 +0100
3.3 @@ -0,0 +1,65 @@
3.4 += OLSR mdns plugin =
3.5 +
3.6 +This README file is the main documentation source for the OLSR mdns plugin
3.7 +
3.8 +Last update 24/03/2009
3.9 +
3.10 +== Description ==
3.11 +
3.12 +This plugin goal is the distribution of multicast DNS messages over an OLSR Wireless Mesh Network.
3.13 +
3.14 +In a wireless mesh network, the usage of wireless interfaces in ad-hoc mode and the OLSR routing protocol prevent
3.15 +multicast messages to be distributed all over the network.
3.16 +
3.17 +We are especially interested in the distribution of Multicast DNS (mDNS) messages, used for host-based service discovery,
3.18 +over the networks that do not directly partecipate in the OLSR mesh cloud.
3.19 +
3.20 +This task is achieved in the following way:
3.21 + 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,
3.22 + 2. the OLSR infrastructure is exploited for the transport of these messages,
3.23 + 3. remote routers decapsulate mDNS messages from received OLSR messages and send them over their attached non-OLSR networks.
3.24 +
3.25 +The work could have its practical and immediate application in all the wireless network communities that employ the OLSR protocol.
3.26 +
3.27 +The plugin captures the traffic (only IPv4 if OLSR is running IPv4 and only IPv6 if OLSR is running IPv6)
3.28 +and encapsulates this traffic in OLSR messages that are forwarded to all the other nodes in the mesh.
3.29 +
3.30 +Other nodes running the plugin will decapsulate the packets and will send them to the interfaces specified in the configuration file
3.31 +
3.32 +Let's get this example topology
3.33 +
3.34 +pc1->eth0 ----- eth0<-r1->ath0 -------ath0<-r2->eth0 ---------eth0<-pc2
3.35 +
3.36 +r1 and r2 are OLSR routers with mdns plugin enabled. pc1 will be able to receive mdns traffic generated at pc2 and vice versa
3.37 +
3.38 +The most interesting feature is that messages are forwarded also by OLSR routers without the plugin. For example:
3.39 +
3.40 +pc1->eth0 ----- eth0<-r1->ath0 ---r3----ath0<-r2->eth0 ---------eth0<-pc2
3.41 +
3.42 +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.
3.43 +
3.44 +== Configuration ==
3.45 +
3.46 +To enable the Plugin use the following syntax
3.47 +
3.48 +LoadPlugin "olsrd_mdns.so.1.0.0"
3.49 +{
3.50 +PlParam "NonOlsrIf" "eth0"
3.51 +PlParam "NonOlsrIf" "eth1"
3.52 +}
3.53 +
3.54 +Where eth0 and eth1 are the names of the interfaces where you want to capture traffic (and decapsulate incoming traffic).
3.55 +
3.56 +Note that this interfaces must not talk OLSR and also the subnets on this interfaces must be announced with an appropriate HNA entry.
3.57 +This version of the plugin will not chech this stuff to be properly configured!
3.58 +
3.59 +
3.60 +
3.61 +=== References ===
3.62 +
3.63 + * Multicast DNS: [http://tools.ietf.org/html/draft-cheshire-dnsext-multicastdns-07 IETF draft-cheshire-dnsext-multicastdns-07]
3.64 + * OLSR Optimized Link State Routing: [http://tools.ietf.org/html/rfc3626 IETF RFC 3626]
3.65 +
3.66 +=== Contact ===
3.67 + * Saverio Proto proto@ing.uniroma2.it
3.68 + * Claudio Pisa claudio.pisa@clauz.net
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/lib/mdns/src/Address.c Thu Mar 26 01:25:34 2009 +0100
4.3 @@ -0,0 +1,60 @@
4.4 +/*
4.5 +OLSR MDNS plugin.
4.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
4.7 +
4.8 + This file is part of OLSR MDNS PLUGIN.
4.9 +
4.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
4.11 + it under the terms of the GNU General Public License as published by
4.12 + the Free Software Foundation, either version 3 of the License, or
4.13 + (at your option) any later version.
4.14 +
4.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
4.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.18 + GNU General Public License for more details.
4.19 +
4.20 + You should have received a copy of the GNU General Public License
4.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
4.22 +
4.23 +
4.24 + */
4.25 +
4.26 +
4.27 +#include "Address.h"
4.28 +
4.29 +/* System includes */
4.30 +#include <stddef.h> /* NULL */
4.31 +#include <string.h> /* strcmp */
4.32 +#include <assert.h> /* assert() */
4.33 +#include <netinet/ip.h> /* struct ip */
4.34 +#include <netinet/udp.h> /* struct udphdr */
4.35 +
4.36 +/* OLSRD includes */
4.37 +#include "defs.h" /* ipequal */
4.38 +#include "olsr_protocol.h" /* OLSRPORT */
4.39 +
4.40 +/* Plugin includes */
4.41 +#include "mdns.h" /* BMF_ENCAP_PORT */
4.42 +#include "NetworkInterfaces.h" /* TBmfInterface */
4.43 +
4.44 +/* Whether or not to flood local broadcast packets (e.g. packets with IP
4.45 + * destination 192.168.1.255). May be overruled by setting the plugin
4.46 + * parameter "DoLocalBroadcast" to "no" */
4.47 +//int EnableLocalBroadcast = 1;
4.48 +
4.49 +/* -------------------------------------------------------------------------
4.50 + * Function : IsMulticast
4.51 + * Description: Check if an IP address is a multicast address
4.52 + * Input : ipAddress
4.53 + * Output : none
4.54 + * Return : true (1) or false (0)
4.55 + * Data Used : none
4.56 + * ------------------------------------------------------------------------- */
4.57 +int IsMulticast(union olsr_ip_addr* ipAddress)
4.58 +{
4.59 + assert(ipAddress != NULL);
4.60 +
4.61 + return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
4.62 +}
4.63 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/lib/mdns/src/Address.h Thu Mar 26 01:25:34 2009 +0100
5.3 @@ -0,0 +1,36 @@
5.4 +/*
5.5 +OLSR MDNS plugin.
5.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
5.7 +
5.8 + This file is part of OLSR MDNS PLUGIN.
5.9 +
5.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
5.11 + it under the terms of the GNU General Public License as published by
5.12 + the Free Software Foundation, either version 3 of the License, or
5.13 + (at your option) any later version.
5.14 +
5.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
5.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
5.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.18 + GNU General Public License for more details.
5.19 +
5.20 + You should have received a copy of the GNU General Public License
5.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
5.22 +
5.23 +
5.24 + */
5.25 +
5.26 +
5.27 +#ifndef _MDNS_ADDRESS_H
5.28 +#define _MDNS_ADDRESS_H
5.29 +
5.30 +#include "olsr_types.h" /* olsr_ip_addr */
5.31 +#include "plugin.h" /* union set_plugin_parameter_addon */
5.32 +#include "interfaces.h" /* struct interface */
5.33 +
5.34 +struct TBmfInterface;
5.35 +
5.36 +int IsMulticast(union olsr_ip_addr* ipAddress);
5.37 +
5.38 +#endif /* _MDNS_ADDRESS_H */
5.39 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/lib/mdns/src/NetworkInterfaces.c Thu Mar 26 01:25:34 2009 +0100
6.3 @@ -0,0 +1,589 @@
6.4 +/*
6.5 +OLSR MDNS plugin.
6.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
6.7 +
6.8 + This file is part of OLSR MDNS PLUGIN.
6.9 +
6.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
6.11 + it under the terms of the GNU General Public License as published by
6.12 + the Free Software Foundation, either version 3 of the License, or
6.13 + (at your option) any later version.
6.14 +
6.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
6.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
6.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.18 + GNU General Public License for more details.
6.19 +
6.20 + You should have received a copy of the GNU General Public License
6.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
6.22 +
6.23 +
6.24 + */
6.25 +
6.26 +
6.27 +#include "NetworkInterfaces.h"
6.28 +
6.29 +/* System includes */
6.30 +#include <stddef.h> /* NULL */
6.31 +#include <syslog.h> /* syslog() */
6.32 +#include <string.h> /* strerror(), strchr(), strcmp() */
6.33 +#include <errno.h> /* errno */
6.34 +#include <unistd.h> /* close() */
6.35 +#include <sys/ioctl.h> /* ioctl() */
6.36 +#include <fcntl.h> /* fcntl() */
6.37 +#include <assert.h> /* assert() */
6.38 +#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
6.39 +#include <netinet/in.h> /* htons() */
6.40 +#include <linux/if_ether.h> /* ETH_P_IP */
6.41 +#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
6.42 +#include <linux/if_tun.h> /* IFF_TAP */
6.43 +#include <netinet/ip.h> /* struct ip */
6.44 +#include <netinet/udp.h> /* SOL_UDP */
6.45 +#include <stdlib.h> /* atoi, malloc */
6.46 +
6.47 +/* OLSRD includes */
6.48 +#include "olsr.h" /* OLSR_PRINTF() */
6.49 +#include "ipcalc.h"
6.50 +#include "defs.h" /* olsr_cnf */
6.51 +#include "link_set.h" /* get_link_set() */
6.52 +#include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
6.53 +#include "net_olsr.h" /* ipequal */
6.54 +#include "lq_plugin.h"
6.55 +#include "olsr_ip_prefix_list.h"
6.56 +
6.57 +/* Plugin includes */
6.58 +#include "Packet.h" /* IFHWADDRLEN */
6.59 +#include "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
6.60 +#include "Address.h" /* IsMulticast() */
6.61 +
6.62 +/* List of network interface objects used by BMF plugin */
6.63 +struct TBmfInterface* BmfInterfaces = NULL;
6.64 +struct TBmfInterface* LastBmfInterface = NULL;
6.65 +
6.66 +/* Highest-numbered open socket file descriptor. To be used as first
6.67 + * parameter in calls to select(...). */
6.68 +int HighestSkfd = -1;
6.69 +
6.70 +/* Set of socket file descriptors */
6.71 +fd_set InputSet;
6.72 +
6.73 +
6.74 +/* -------------------------------------------------------------------------
6.75 + * Function : CreateCaptureSocket
6.76 + * Description: Create socket for promiscuously capturing multicast IP traffic
6.77 + * Input : ifname - network interface (e.g. "eth0")
6.78 + * Output : none
6.79 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
6.80 + * Data Used : none
6.81 + * Notes : The socket is a cooked IP packet socket, bound to the specified
6.82 + * network interface
6.83 + * ------------------------------------------------------------------------- */
6.84 +static int CreateCaptureSocket(const char* ifName)
6.85 +{
6.86 + int ifIndex = if_nametoindex(ifName);
6.87 + struct packet_mreq mreq;
6.88 + struct ifreq req;
6.89 + struct sockaddr_ll bindTo;
6.90 + int skfd = 0;
6.91 + /* Open cooked IP packet socket */
6.92 + if (olsr_cnf->ip_version == AF_INET){
6.93 + skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
6.94 + }
6.95 + else {
6.96 + skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
6.97 + }
6.98 + if (skfd < 0)
6.99 + {
6.100 + BmfPError("socket(PF_PACKET) error");
6.101 + return -1;
6.102 + }
6.103 +
6.104 + /* Set interface to promiscuous mode */
6.105 + memset(&mreq, 0, sizeof(struct packet_mreq));
6.106 + mreq.mr_ifindex = ifIndex;
6.107 + mreq.mr_type = PACKET_MR_PROMISC;
6.108 + if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
6.109 + {
6.110 + BmfPError("setsockopt(PACKET_MR_PROMISC) error");
6.111 + close(skfd);
6.112 + return -1;
6.113 + }
6.114 +
6.115 + /* Get hardware (MAC) address */
6.116 + memset(&req, 0, sizeof(struct ifreq));
6.117 + strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
6.118 + req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
6.119 + if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
6.120 + {
6.121 + BmfPError("error retrieving MAC address");
6.122 + close(skfd);
6.123 + return -1;
6.124 + }
6.125 +
6.126 + /* Bind the socket to the specified interface */
6.127 + memset(&bindTo, 0, sizeof(bindTo));
6.128 + bindTo.sll_family = AF_PACKET;
6.129 + if (olsr_cnf->ip_version == AF_INET){
6.130 + bindTo.sll_protocol = htons(ETH_P_IP);
6.131 + }
6.132 + else{
6.133 + bindTo.sll_protocol = htons(ETH_P_IPV6);
6.134 + }
6.135 + bindTo.sll_ifindex = ifIndex;
6.136 + memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
6.137 + bindTo.sll_halen = IFHWADDRLEN;
6.138 +
6.139 + if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
6.140 + {
6.141 + BmfPError("bind() error");
6.142 + close(skfd);
6.143 + return -1;
6.144 + }
6.145 +
6.146 + /* Set socket to blocking operation */
6.147 + if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
6.148 + {
6.149 + BmfPError("fcntl() error");
6.150 + close(skfd);
6.151 + return -1;
6.152 + }
6.153 +
6.154 + //AddDescriptorToInputSet(skfd);
6.155 + add_olsr_socket(skfd,&DoMDNS,NULL,NULL,SP_PR_READ);
6.156 +
6.157 + return skfd;
6.158 +} /* CreateCaptureSocket */
6.159 +
6.160 +/* -------------------------------------------------------------------------
6.161 + * Function : CreateInterface
6.162 + * Description: Create a new TBmfInterface object and adds it to the global
6.163 + * BmfInterfaces list
6.164 + * Input : ifName - name of the network interface (e.g. "eth0")
6.165 + * : olsrIntf - OLSR interface object of the network interface, or
6.166 + * NULL if the network interface is not OLSR-enabled
6.167 + * Output : none
6.168 + * Return : the number of opened sockets
6.169 + * Data Used : BmfInterfaces, LastBmfInterface
6.170 + * ------------------------------------------------------------------------- */
6.171 +
6.172 +//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
6.173 +
6.174 +static int CreateInterface(
6.175 + const char* ifName,
6.176 + struct interface* olsrIntf)
6.177 +{
6.178 + int capturingSkfd = -1;
6.179 + int encapsulatingSkfd = -1;
6.180 + int listeningSkfd = -1;
6.181 + int ioctlSkfd;
6.182 + struct ifreq ifr;
6.183 + int nOpened = 0;
6.184 + struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
6.185 +
6.186 + assert(ifName != NULL);
6.187 +
6.188 + if (newIf == NULL)
6.189 + {
6.190 + return 0;
6.191 + }
6.192 +
6.193 +//TODO: assert interface is not talking OLSR
6.194 +
6.195 +
6.196 + /* Create socket for capturing and sending of multicast packets on
6.197 + * non-OLSR interfaces, and on OLSR-interfaces if configured. */
6.198 + if ((olsrIntf == NULL) )
6.199 + {
6.200 + capturingSkfd = CreateCaptureSocket(ifName);
6.201 + if (capturingSkfd < 0)
6.202 + {
6.203 + close(encapsulatingSkfd);
6.204 + free(newIf);
6.205 + return 0;
6.206 + }
6.207 +
6.208 + nOpened++;
6.209 + }
6.210 +
6.211 + /* For ioctl operations on the network interface, use either capturingSkfd
6.212 + * or encapsulatingSkfd, whichever is available */
6.213 + ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
6.214 +
6.215 + /* Retrieve the MAC address of the interface. */
6.216 + memset(&ifr, 0, sizeof(struct ifreq));
6.217 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
6.218 + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
6.219 + if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0)
6.220 + {
6.221 + BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
6.222 + close(capturingSkfd);
6.223 + close(encapsulatingSkfd);
6.224 + free(newIf);
6.225 + return 0;
6.226 + }
6.227 +
6.228 + /* Copy data into TBmfInterface object */
6.229 + newIf->capturingSkfd = capturingSkfd;
6.230 + newIf->encapsulatingSkfd = encapsulatingSkfd;
6.231 + newIf->listeningSkfd = listeningSkfd;
6.232 + memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
6.233 + memcpy(newIf->ifName, ifName, IFNAMSIZ);
6.234 + newIf->olsrIntf = olsrIntf;
6.235 + if (olsrIntf != NULL)
6.236 + {
6.237 + /* For an OLSR-interface, copy the interface address and broadcast
6.238 + * address from the OLSR interface object. Downcast to correct sockaddr
6.239 + * subtype. */
6.240 + newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
6.241 + newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
6.242 + }
6.243 + else
6.244 + {
6.245 + /* For a non-OLSR interface, retrieve the IP address ourselves */
6.246 + memset(&ifr, 0, sizeof(struct ifreq));
6.247 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
6.248 + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
6.249 + if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0)
6.250 + {
6.251 + BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
6.252 +
6.253 + newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
6.254 + }
6.255 + else
6.256 + {
6.257 + /* Downcast to correct sockaddr subtype */
6.258 + newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
6.259 + }
6.260 +
6.261 + /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
6.262 + memset(&ifr, 0, sizeof(struct ifreq));
6.263 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
6.264 + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
6.265 + if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0)
6.266 + {
6.267 + BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
6.268 +
6.269 + newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
6.270 + }
6.271 + else
6.272 + {
6.273 + /* Downcast to correct sockaddr subtype */
6.274 + newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
6.275 + }
6.276 + }
6.277 +
6.278 + /* Initialize fragment history table */
6.279 + //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
6.280 + //newIf->nextFragmentHistoryEntry = 0;
6.281 +
6.282 + /* Reset counters */
6.283 + //newIf->nBmfPacketsRx = 0;
6.284 + //newIf->nBmfPacketsRxDup = 0;
6.285 + //newIf->nBmfPacketsTx = 0;
6.286 +
6.287 + /* Add new TBmfInterface object to global list. OLSR interfaces are
6.288 + * added at the front of the list, non-OLSR interfaces at the back. */
6.289 + if (BmfInterfaces == NULL)
6.290 + {
6.291 + /* First TBmfInterface object in list */
6.292 + BmfInterfaces = newIf;
6.293 + LastBmfInterface = newIf;
6.294 + }
6.295 + else if (olsrIntf != NULL)
6.296 + {
6.297 + /* Add new TBmfInterface object at front of list */
6.298 + newIf->next = BmfInterfaces;
6.299 + BmfInterfaces = newIf;
6.300 + }
6.301 + else
6.302 + {
6.303 + /* Add new TBmfInterface object at back of list */
6.304 + newIf->next = NULL;
6.305 + LastBmfInterface->next= newIf;
6.306 + LastBmfInterface = newIf;
6.307 + }
6.308 +
6.309 + //OLSR_PRINTF(
6.310 + // 8,
6.311 + // "%s: opened %d socket%s on %s interface \"%s\"\n",
6.312 + // PLUGIN_NAME_SHORT,
6.313 + // nOpened,
6.314 + // nOpened == 1 ? "" : "s",
6.315 + // olsrIntf != NULL ? "OLSR" : "non-OLSR",
6.316 + // ifName);
6.317 +
6.318 + return nOpened;
6.319 +} /* CreateInterface */
6.320 +
6.321 +/* -------------------------------------------------------------------------
6.322 + * Function : CreateBmfNetworkInterfaces
6.323 + * Description: Create a list of TBmfInterface objects, one for each network
6.324 + * interface on which BMF runs
6.325 + * Input : skipThisIntf - network interface to skip, if seen
6.326 + * Output : none
6.327 + * Return : fail (-1) or success (0)
6.328 + * Data Used : none
6.329 + * ------------------------------------------------------------------------- */
6.330 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
6.331 +{
6.332 + int skfd;
6.333 + struct ifconf ifc;
6.334 + int numreqs = 30;
6.335 + struct ifreq* ifr;
6.336 + int n;
6.337 + int nOpenedSockets = 0;
6.338 +
6.339 + /* Clear input descriptor set */
6.340 + FD_ZERO(&InputSet);
6.341 +
6.342 + skfd = socket(PF_INET, SOCK_DGRAM, 0);
6.343 + if (skfd < 0)
6.344 + {
6.345 + BmfPError("no inet socket available to retrieve interface list");
6.346 + return -1;
6.347 + }
6.348 +
6.349 + /* Retrieve the network interface configuration list */
6.350 + ifc.ifc_buf = NULL;
6.351 + for (;;)
6.352 + {
6.353 + ifc.ifc_len = sizeof(struct ifreq) * numreqs;
6.354 + ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
6.355 +
6.356 + if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
6.357 + {
6.358 + BmfPError("ioctl(SIOCGIFCONF) error");
6.359 +
6.360 + close(skfd);
6.361 + free(ifc.ifc_buf);
6.362 + return -1;
6.363 + }
6.364 + if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
6.365 + {
6.366 + /* Assume it overflowed; double the space and try again */
6.367 + numreqs *= 2;
6.368 + assert(numreqs < 1024);
6.369 + continue; /* for (;;) */
6.370 + }
6.371 + break; /* for (;;) */
6.372 + } /* for (;;) */
6.373 +
6.374 + close(skfd);
6.375 +
6.376 + /* For each item in the interface configuration list... */
6.377 + ifr = ifc.ifc_req;
6.378 + for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
6.379 + {
6.380 + struct interface* olsrIntf;
6.381 + union olsr_ip_addr ipAddr;
6.382 +
6.383 + /* Skip the BMF network interface itself */
6.384 + //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
6.385 + //{
6.386 + // continue; /* for (n = ...) */
6.387 + //}
6.388 +
6.389 + /* ...find the OLSR interface structure, if any */
6.390 + ipAddr.v4 = ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
6.391 + olsrIntf = if_ifwithaddr(&ipAddr);
6.392 +
6.393 + if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
6.394 + {
6.395 + continue; /* for (n = ...) */
6.396 + }
6.397 +
6.398 + if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
6.399 + {
6.400 + /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
6.401 + * interface in the BMF plugin parameter list */
6.402 + continue; /* for (n = ...) */
6.403 + }
6.404 +
6.405 + if (! IsNonOlsrBmfIf(ifr->ifr_name))
6.406 + {
6.407 + //If the interface is not specified in the configuration file then go ahead
6.408 + continue; /* for (n = ...) */
6.409 + }
6.410 + //TODO: asser if->ifr_name is not talking OLSR
6.411 + //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
6.412 + nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
6.413 +
6.414 + } /* for (n = ...) */
6.415 +
6.416 + free(ifc.ifc_buf);
6.417 +
6.418 + if (BmfInterfaces == NULL)
6.419 + {
6.420 + //OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
6.421 + }
6.422 + else
6.423 + {
6.424 + //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
6.425 + }
6.426 + return 0;
6.427 +} /* CreateBmfNetworkInterfaces */
6.428 +
6.429 +/* -------------------------------------------------------------------------
6.430 + * Function : AddInterface
6.431 + * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
6.432 + * network interfaces
6.433 + * Input : newIntf - network interface to add
6.434 + * Output : none
6.435 + * Return : none
6.436 + * Data Used : none
6.437 + * ------------------------------------------------------------------------- */
6.438 +void AddInterface(struct interface* newIntf)
6.439 +{
6.440 + int nOpened;
6.441 +
6.442 + assert(newIntf != NULL);
6.443 +
6.444 + nOpened = CreateInterface(newIntf->int_name, newIntf);
6.445 +
6.446 + //OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
6.447 +} /* AddInterface */
6.448 +
6.449 +/* -------------------------------------------------------------------------
6.450 + * Function : CloseBmfNetworkInterfaces
6.451 + * Description: Closes every socket on each network interface used by BMF
6.452 + * Input : none
6.453 + * Output : none
6.454 + * Return : none
6.455 + * Data Used : none
6.456 + * Notes : Closes
6.457 + * - the local EtherTunTap interface (e.g. "tun0" or "tap0")
6.458 + * - for each BMF-enabled interface, the socket used for
6.459 + * capturing multicast packets
6.460 + * - for each OLSR-enabled interface, the socket used for
6.461 + * encapsulating packets
6.462 + * Also restores the network state to the situation before BMF
6.463 + * was started.
6.464 + * ------------------------------------------------------------------------- */
6.465 +void CloseBmfNetworkInterfaces(void)
6.466 +{
6.467 + int nClosed = 0;
6.468 + u_int32_t totalOlsrBmfPacketsRx = 0;
6.469 + u_int32_t totalOlsrBmfPacketsRxDup = 0;
6.470 + u_int32_t totalOlsrBmfPacketsTx = 0;
6.471 + u_int32_t totalNonOlsrBmfPacketsRx = 0;
6.472 + u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
6.473 + u_int32_t totalNonOlsrBmfPacketsTx = 0;
6.474 +
6.475 + /* Close all opened sockets */
6.476 + struct TBmfInterface* nextBmfIf = BmfInterfaces;
6.477 + while (nextBmfIf != NULL)
6.478 + {
6.479 + struct TBmfInterface* bmfIf = nextBmfIf;
6.480 + nextBmfIf = bmfIf->next;
6.481 +
6.482 + if (bmfIf->capturingSkfd >= 0)
6.483 + {
6.484 + close(bmfIf->capturingSkfd);
6.485 + nClosed++;
6.486 + }
6.487 + if (bmfIf->encapsulatingSkfd >= 0)
6.488 + {
6.489 + close(bmfIf->encapsulatingSkfd);
6.490 + nClosed++;
6.491 + }
6.492 +
6.493 + //OLSR_PRINTF(
6.494 + // 7,
6.495 + // "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
6.496 + // PLUGIN_NAME_SHORT,
6.497 + // bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
6.498 + // bmfIf->ifName,
6.499 + // bmfIf->nBmfPacketsRx,
6.500 + // bmfIf->nBmfPacketsRxDup,
6.501 + // bmfIf->nBmfPacketsTx);
6.502 +
6.503 + //OLSR_PRINTF(
6.504 + // 1,
6.505 + // "%s: closed %s interface \"%s\"\n",
6.506 + // PLUGIN_NAME_SHORT,
6.507 + // bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
6.508 + // bmfIf->ifName);
6.509 +
6.510 + /* Add totals */
6.511 + if (bmfIf->olsrIntf != NULL)
6.512 + {
6.513 + totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
6.514 + totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
6.515 + totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
6.516 + }
6.517 + else
6.518 + {
6.519 + totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
6.520 + totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
6.521 + totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
6.522 + }
6.523 +
6.524 + free(bmfIf);
6.525 + } /* while */
6.526 +
6.527 + BmfInterfaces = NULL;
6.528 +
6.529 + //OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
6.530 +
6.531 +} /* CloseBmfNetworkInterfaces */
6.532 +
6.533 +#define MAX_NON_OLSR_IFS 32
6.534 +static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
6.535 +static int nNonOlsrIfs = 0;
6.536 +
6.537 +/* -------------------------------------------------------------------------
6.538 + * Function : AddNonOlsrBmfIf
6.539 + * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
6.540 + * network interfaces
6.541 + * Input : ifName - network interface (e.g. "eth0")
6.542 + * data - not used
6.543 + * addon - not used
6.544 + * Output : none
6.545 + * Return : success (0) or fail (1)
6.546 + * Data Used : NonOlsrIfNames
6.547 + * ------------------------------------------------------------------------- */
6.548 +int AddNonOlsrBmfIf(
6.549 + const char* ifName,
6.550 + void* data __attribute__((unused)),
6.551 + set_plugin_parameter_addon addon __attribute__((unused)))
6.552 +{
6.553 + assert(ifName != NULL);
6.554 +
6.555 + if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
6.556 + {
6.557 + //OLSR_PRINTF(
6.558 + // 1,
6.559 + // "%s: too many non-OLSR interfaces specified, maximum is %d\n",
6.560 + // PLUGIN_NAME,
6.561 + // MAX_NON_OLSR_IFS);
6.562 + return 1;
6.563 + }
6.564 +
6.565 + strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
6.566 + NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
6.567 + nNonOlsrIfs++;
6.568 + return 0;
6.569 +} /* AddNonOlsrBmfIf */
6.570 +
6.571 +/* -------------------------------------------------------------------------
6.572 + * Function : IsNonOlsrBmfIf
6.573 + * Description: Checks if a network interface is OLSR-enabled
6.574 + * Input : ifName - network interface (e.g. "eth0")
6.575 + * Output : none
6.576 + * Return : true (1) or false (0)
6.577 + * Data Used : NonOlsrIfNames
6.578 + * ------------------------------------------------------------------------- */
6.579 +int IsNonOlsrBmfIf(const char* ifName)
6.580 +{
6.581 + int i;
6.582 +
6.583 + assert(ifName != NULL);
6.584 +
6.585 + for (i = 0; i < nNonOlsrIfs; i++)
6.586 + {
6.587 + if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
6.588 + }
6.589 + return 0;
6.590 +} /* IsNonOlsrBmfIf */
6.591 +
6.592 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/lib/mdns/src/NetworkInterfaces.h Thu Mar 26 01:25:34 2009 +0100
7.3 @@ -0,0 +1,145 @@
7.4 +/*
7.5 +OLSR MDNS plugin.
7.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
7.7 +
7.8 + This file is part of OLSR MDNS PLUGIN.
7.9 +
7.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
7.11 + it under the terms of the GNU General Public License as published by
7.12 + the Free Software Foundation, either version 3 of the License, or
7.13 + (at your option) any later version.
7.14 +
7.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
7.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
7.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.18 + GNU General Public License for more details.
7.19 +
7.20 + You should have received a copy of the GNU General Public License
7.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
7.22 +
7.23 +
7.24 + */
7.25 +
7.26 +
7.27 +#ifndef _BMF_NETWORKINTERFACES_H
7.28 +#define _BMF_NETWORKINTERFACES_H
7.29 +
7.30 +/* System includes */
7.31 +#include <netinet/in.h> /* struct in_addr */
7.32 +
7.33 +/* OLSR includes */
7.34 +#include "olsr_types.h" /* olsr_ip_addr */
7.35 +#include "plugin.h" /* union set_plugin_parameter_addon */
7.36 +
7.37 +/* Plugin includes */
7.38 +#include "Packet.h" /* IFHWADDRLEN */
7.39 +#include "mdns.h"
7.40 +/* Size of buffer in which packets are received */
7.41 +#define BMF_BUFFER_SIZE 2048
7.42 +
7.43 +struct TBmfInterface
7.44 +{
7.45 + /* File descriptor of raw packet socket, used for capturing multicast packets */
7.46 + int capturingSkfd;
7.47 +
7.48 + /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
7.49 + * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
7.50 + int encapsulatingSkfd;
7.51 +
7.52 + /* File descriptor of UDP packet socket, used for listening to encapsulation packets.
7.53 + * Used only when PlParam "BmfMechanism" is set to "UnicastPromiscuous". */
7.54 + int listeningSkfd;
7.55 +
7.56 + unsigned char macAddr[IFHWADDRLEN];
7.57 +
7.58 + char ifName[IFNAMSIZ];
7.59 +
7.60 + /* OLSRs idea of this network interface. NULL if this interface is not
7.61 + * OLSR-enabled. */
7.62 + struct interface* olsrIntf;
7.63 +
7.64 + /* IP address of this network interface */
7.65 + union olsr_ip_addr intAddr;
7.66 +
7.67 + /* Broadcast address of this network interface */
7.68 + union olsr_ip_addr broadAddr;
7.69 +
7.70 + #define FRAGMENT_HISTORY_SIZE 10
7.71 + struct TFragmentHistory
7.72 + {
7.73 + u_int16_t ipId;
7.74 + u_int8_t ipProto;
7.75 + struct in_addr ipSrc;
7.76 + struct in_addr ipDst;
7.77 + } fragmentHistory [FRAGMENT_HISTORY_SIZE];
7.78 +
7.79 + int nextFragmentHistoryEntry;
7.80 +
7.81 + /* Number of received and transmitted BMF packets on this interface */
7.82 + u_int32_t nBmfPacketsRx;
7.83 + u_int32_t nBmfPacketsRxDup;
7.84 + u_int32_t nBmfPacketsTx;
7.85 +
7.86 + /* Next element in list */
7.87 + struct TBmfInterface* next;
7.88 +};
7.89 +
7.90 +extern struct TBmfInterface* BmfInterfaces;
7.91 +
7.92 +extern int HighestSkfd;
7.93 +extern fd_set InputSet;
7.94 +
7.95 +extern int EtherTunTapFd;
7.96 +
7.97 +extern char EtherTunTapIfName[];
7.98 +
7.99 +/* 10.255.255.253 in host byte order */
7.100 +#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD
7.101 +
7.102 +extern u_int32_t EtherTunTapIp;
7.103 +extern u_int32_t EtherTunTapIpMask;
7.104 +extern u_int32_t EtherTunTapIpBroadcast;
7.105 +
7.106 +
7.107 +enum TBmfMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
7.108 +extern enum TBmfMechanism BmfMechanism;
7.109 +
7.110 +int SetBmfInterfaceName(const char* ifname, void* data, set_plugin_parameter_addon addon);
7.111 +int SetBmfInterfaceIp(const char* ip, void* data, set_plugin_parameter_addon addon);
7.112 +int SetCapturePacketsOnOlsrInterfaces(const char* enable, void* data, set_plugin_parameter_addon addon);
7.113 +int SetBmfMechanism(const char* mechanism, void* data, set_plugin_parameter_addon addon);
7.114 +int DeactivateSpoofFilter(void);
7.115 +void RestoreSpoofFilter(void);
7.116 +
7.117 +#define MAX_UNICAST_NEIGHBORS 10
7.118 +struct TBestNeighbors
7.119 +{
7.120 + struct link_entry* links[MAX_UNICAST_NEIGHBORS];
7.121 +};
7.122 +
7.123 +void FindNeighbors(
7.124 + struct TBestNeighbors* neighbors,
7.125 + struct link_entry** bestNeighbor,
7.126 + struct TBmfInterface* intf,
7.127 + union olsr_ip_addr* source,
7.128 + union olsr_ip_addr* forwardedBy,
7.129 + union olsr_ip_addr* forwardedTo,
7.130 + int* nPossibleNeighbors);
7.131 +
7.132 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
7.133 +void AddInterface(struct interface* newIntf);
7.134 +void CloseBmfNetworkInterfaces(void);
7.135 +int AddNonOlsrBmfIf(const char* ifName, void* data, set_plugin_parameter_addon addon);
7.136 +int IsNonOlsrBmfIf(const char* ifName);
7.137 +void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr);
7.138 +void AddMulticastRoute(void);
7.139 +void DeleteMulticastRoute(void);
7.140 +
7.141 +#endif /* _BMF_NETWORKINTERFACES_H */
7.142 +
7.143 +/*
7.144 + * Local Variables:
7.145 + * c-basic-offset: 2
7.146 + * indent-tabs-mode: nil
7.147 + * End:
7.148 + */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/lib/mdns/src/Packet.c Thu Mar 26 01:25:34 2009 +0100
8.3 @@ -0,0 +1,210 @@
8.4 +/*
8.5 +OLSR MDNS plugin.
8.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
8.7 +
8.8 + This file is part of OLSR MDNS PLUGIN.
8.9 +
8.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
8.11 + it under the terms of the GNU General Public License as published by
8.12 + the Free Software Foundation, either version 3 of the License, or
8.13 + (at your option) any later version.
8.14 +
8.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
8.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
8.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.18 + GNU General Public License for more details.
8.19 +
8.20 + You should have received a copy of the GNU General Public License
8.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
8.22 +
8.23 +
8.24 + */
8.25 +
8.26 +#include "Packet.h"
8.27 +
8.28 +/* System includes */
8.29 +#include <stddef.h> /* NULL */
8.30 +#include <assert.h> /* assert() */
8.31 +#include <string.h> /* memcpy() */
8.32 +#include <sys/types.h> /* u_int8_t, u_int16_t, u_int32_t */
8.33 +#include <netinet/in.h> /* ntohs(), htons() */
8.34 +#include <netinet/ip.h> /* struct iphdr */
8.35 +
8.36 +/* -------------------------------------------------------------------------
8.37 + * Function : IsIpFragment
8.38 + * Description: Check if an IP packet is an IP fragment
8.39 + * Input : ipPacket - the IP packet
8.40 + * Output : none
8.41 + * Return : true (1) or false (0)
8.42 + * Data Used : none
8.43 + * ------------------------------------------------------------------------- */
8.44 +int IsIpFragment(unsigned char* ipPacket)
8.45 +{
8.46 + struct ip* iph;
8.47 +
8.48 + assert(ipPacket != NULL);
8.49 +
8.50 + iph = (struct ip*) ipPacket;
8.51 + if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
8.52 + {
8.53 + return 1;
8.54 + }
8.55 + return 0;
8.56 +} /* IsIpFragment */
8.57 +
8.58 +/* -------------------------------------------------------------------------
8.59 + * Function : GetIpTotalLength
8.60 + * Description: Retrieve the total length of the IP packet (in bytes) of
8.61 + * an IP packet
8.62 + * Input : ipPacket - the IP packet
8.63 + * Output : none
8.64 + * Return : IP packet length
8.65 + * Data Used : none
8.66 + * ------------------------------------------------------------------------- */
8.67 +u_int16_t GetIpTotalLength(unsigned char* ipPacket)
8.68 +{
8.69 + struct iphdr* iph;
8.70 +
8.71 + assert(ipPacket != NULL);
8.72 +
8.73 + iph = (struct iphdr*) ipPacket;
8.74 + return ntohs(iph->tot_len);
8.75 +} /* GetIpTotalLength */
8.76 +
8.77 +/* -------------------------------------------------------------------------
8.78 + * Function : GetIpHeaderLength
8.79 + * Description: Retrieve the IP header length (in bytes) of an IP packet
8.80 + * Input : ipPacket - the IP packet
8.81 + * Output : none
8.82 + * Return : IP header length
8.83 + * Data Used : none
8.84 + * ------------------------------------------------------------------------- */
8.85 +unsigned int GetIpHeaderLength(unsigned char* ipPacket)
8.86 +{
8.87 + struct iphdr* iph;
8.88 +
8.89 + assert(ipPacket != NULL);
8.90 +
8.91 + iph = (struct iphdr*) ipPacket;
8.92 + return iph->ihl << 2;
8.93 +} /* GetIpHeaderLength */
8.94 +
8.95 +/* -------------------------------------------------------------------------
8.96 + * Function : GetTtl
8.97 + * Description: Retrieve the TTL (Time To Live) value from the IP header of
8.98 + * an IP packet
8.99 + * Input : ipPacket - the IP packet
8.100 + * Output : none
8.101 + * Return : TTL value
8.102 + * Data Used : none
8.103 + * ------------------------------------------------------------------------- */
8.104 +u_int8_t GetTtl(unsigned char* ipPacket)
8.105 +{
8.106 + struct iphdr* iph;
8.107 +
8.108 + assert(ipPacket != NULL);
8.109 +
8.110 + iph = (struct iphdr*) ipPacket;
8.111 + return iph->ttl;
8.112 +} /* GetTtl */
8.113 +
8.114 +/* -------------------------------------------------------------------------
8.115 + * Function : SaveTtlAndChecksum
8.116 + * Description: Save the TTL (Time To Live) value and IP checksum as found in
8.117 + * the IP header of an IP packet
8.118 + * Input : ipPacket - the IP packet
8.119 + * Output : sttl - the TTL and checksum values
8.120 + * Return : none
8.121 + * Data Used : none
8.122 + * ------------------------------------------------------------------------- */
8.123 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
8.124 +{
8.125 + struct iphdr* iph;
8.126 +
8.127 + assert(ipPacket != NULL && sttl != NULL);
8.128 +
8.129 + iph = (struct iphdr*) ipPacket;
8.130 + sttl->ttl = iph->ttl;
8.131 + sttl->check = ntohs(iph->check);
8.132 +} /* SaveTtlAndChecksum */
8.133 +
8.134 +/* -------------------------------------------------------------------------
8.135 + * Function : RestoreTtlAndChecksum
8.136 + * Description: Restore the TTL (Time To Live) value and IP checksum in
8.137 + * the IP header of an IP packet
8.138 + * Input : ipPacket - the IP packet
8.139 + * sttl - the TTL and checksum values
8.140 + * Output : none
8.141 + * Return : none
8.142 + * Data Used : none
8.143 + * ------------------------------------------------------------------------- */
8.144 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
8.145 +{
8.146 + struct iphdr* iph;
8.147 +
8.148 + assert(ipPacket != NULL && sttl != NULL);
8.149 +
8.150 + iph = (struct iphdr*) ipPacket;
8.151 + iph->ttl = sttl->ttl;
8.152 + iph->check = htons(sttl->check);
8.153 +} /* RestoreTtlAndChecksum */
8.154 +
8.155 +/* -------------------------------------------------------------------------
8.156 + * Function : DecreaseTtlAndUpdateHeaderChecksum
8.157 + * Description: For an IP packet, decrement the TTL value and update the IP header
8.158 + * checksum accordingly.
8.159 + * Input : ipPacket - the IP packet
8.160 + * Output : none
8.161 + * Return : none
8.162 + * Data Used : none
8.163 + * Notes : See also RFC1141
8.164 + * ------------------------------------------------------------------------- */
8.165 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
8.166 +{
8.167 + struct iphdr* iph;
8.168 + u_int32_t sum;
8.169 +
8.170 + assert(ipPacket != NULL);
8.171 +
8.172 + iph = (struct iphdr*) ipPacket;
8.173 +
8.174 + iph->ttl--; /* decrement ttl */
8.175 + sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
8.176 + iph->check = htons(sum + (sum>>16)); /* add carry */
8.177 +} /* DecreaseTtlAndUpdateHeaderChecksum */
8.178 +
8.179 +/* -------------------------------------------------------------------------
8.180 + * Function : GetIpHeader
8.181 + * Description: Retrieve the IP header from BMF encapsulation UDP data
8.182 + * Input : encapsulationUdpData - the encapsulation UDP data
8.183 + * Output : none
8.184 + * Return : IP header
8.185 + * Data Used : none
8.186 + * ------------------------------------------------------------------------- */
8.187 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
8.188 +{
8.189 + return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
8.190 +} /* GetIpHeader */
8.191 +
8.192 +/* -------------------------------------------------------------------------
8.193 + * Function : GetIpPacket
8.194 + * Description: Retrieve the IP packet from BMF encapsulation UDP data
8.195 + * Input : encapsulationUdpData - the encapsulation UDP data
8.196 + * Output : none
8.197 + * Return : The IP packet
8.198 + * Data Used : none
8.199 + * ------------------------------------------------------------------------- */
8.200 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
8.201 +{
8.202 + return encapsulationUdpData + ENCAP_HDR_LEN;
8.203 +} /* GetIpPacket */
8.204 +
8.205 +
8.206 +
8.207 +
8.208 +/*
8.209 + * Local Variables:
8.210 + * c-basic-offset: 2
8.211 + * indent-tabs-mode: nil
8.212 + * End:
8.213 + */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/lib/mdns/src/Packet.h Thu Mar 26 01:25:34 2009 +0100
9.3 @@ -0,0 +1,66 @@
9.4 +/*
9.5 +OLSR MDNS plugin.
9.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
9.7 +
9.8 + This file is part of OLSR MDNS PLUGIN.
9.9 +
9.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
9.11 + it under the terms of the GNU General Public License as published by
9.12 + the Free Software Foundation, either version 3 of the License, or
9.13 + (at your option) any later version.
9.14 +
9.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
9.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
9.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.18 + GNU General Public License for more details.
9.19 +
9.20 + You should have received a copy of the GNU General Public License
9.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
9.22 +
9.23 +
9.24 + */
9.25 +
9.26 +
9.27 +#ifndef _MDNS_PACKET_H
9.28 +#define _MDNS_PACKET_H
9.29 +
9.30 +
9.31 +/* System includes */
9.32 +#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
9.33 +#include <sys/types.h> /* u_int8_t, u_int16_t */
9.34 +
9.35 +/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
9.36 + * with a 8-bytes BMF header (struct TEncapHeader), followed by the
9.37 + * encapsulated Ethernet-IP packet itself */
9.38 +
9.39 +struct TEncapHeader
9.40 +{
9.41 + /* Use a standard Type-Length-Value (TLV) element */
9.42 + u_int8_t type;
9.43 + u_int8_t len;
9.44 + u_int16_t reserved; /* Always 0 */
9.45 + u_int32_t crc32;
9.46 +} __attribute__((__packed__));
9.47 +
9.48 +#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))
9.49 +#define BMF_ENCAP_TYPE 1
9.50 +#define BMF_ENCAP_LEN 6
9.51 +
9.52 +struct TSaveTtl
9.53 +{
9.54 + u_int8_t ttl;
9.55 + u_int16_t check;
9.56 +} __attribute__((__packed__));
9.57 +
9.58 +int IsIpFragment(unsigned char* ipPacket);
9.59 +u_int16_t GetIpTotalLength(unsigned char* ipPacket);
9.60 +unsigned int GetIpHeaderLength(unsigned char* ipPacket);
9.61 +u_int8_t GetTtl(unsigned char* ipPacket);
9.62 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
9.63 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
9.64 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket);
9.65 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData);
9.66 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData);
9.67 +
9.68 +#endif /* _MDNS_PACKET_H */
9.69 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/lib/mdns/src/mdns.c Thu Mar 26 01:25:34 2009 +0100
10.3 @@ -0,0 +1,485 @@
10.4 +/*
10.5 +OLSR MDNS plugin.
10.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
10.7 +
10.8 + This file is part of OLSR MDNS PLUGIN.
10.9 +
10.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
10.11 + it under the terms of the GNU General Public License as published by
10.12 + the Free Software Foundation, either version 3 of the License, or
10.13 + (at your option) any later version.
10.14 +
10.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
10.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
10.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.18 + GNU General Public License for more details.
10.19 +
10.20 + You should have received a copy of the GNU General Public License
10.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
10.22 +
10.23 +
10.24 + */
10.25 +
10.26 +
10.27 +#include "mdns.h"
10.28 +
10.29 +/* System includes */
10.30 +#include <stddef.h> /* NULL */
10.31 +#include <sys/types.h> /* ssize_t */
10.32 +#include <string.h> /* strerror() */
10.33 +#include <stdarg.h> /* va_list, va_start, va_end */
10.34 +#include <errno.h> /* errno */
10.35 +#include <assert.h> /* assert() */
10.36 +#include <linux/if_ether.h> /* ETH_P_IP */
10.37 +#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
10.38 +//#include <pthread.h> /* pthread_t, pthread_create() */
10.39 +#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
10.40 +#include <netinet/ip.h> /* struct ip */
10.41 +#include <netinet/udp.h> /* struct udphdr */
10.42 +#include <unistd.h> /* close() */
10.43 +
10.44 +#include <netinet/in.h>
10.45 +#include <netinet/ip6.h>
10.46 +
10.47 +/* OLSRD includes */
10.48 +#include "plugin_util.h" /* set_plugin_int */
10.49 +#include "defs.h" /* olsr_cnf, //OLSR_PRINTF */
10.50 +#include "ipcalc.h"
10.51 +#include "olsr.h" /* //OLSR_PRINTF */
10.52 +#include "mid_set.h" /* mid_lookup_main_addr() */
10.53 +#include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
10.54 +#include "link_set.h" /* get_best_link_to_neighbor() */
10.55 +#include "net_olsr.h" /* ipequal */
10.56 +
10.57 +/* plugin includes */
10.58 +#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
10.59 +#include "Address.h" /* IsMulticast() */
10.60 +#include "Packet.h" /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
10.61 +
10.62 +
10.63 +/* -------------------------------------------------------------------------
10.64 + * Function : PacketReceivedFromOLSR
10.65 + * Description: Handle a received packet from a OLSR message
10.66 + * Input : ipPacket into an unsigned char and the lenght of the packet
10.67 + * Output : none
10.68 + * Return : none
10.69 + * Data Used : BmfInterfaces
10.70 + * ------------------------------------------------------------------------- */
10.71 +static void PacketReceivedFromOLSR(
10.72 + unsigned char* encapsulationUdpData, int len)
10.73 +{
10.74 + struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
10.75 + union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
10.76 + union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
10.77 + struct TBmfInterface* walker;
10.78 + ipHeader = (struct ip*) encapsulationUdpData;
10.79 + mcSrc.v4 = ipHeader->ip_src;
10.80 + mcDst.v4 = ipHeader->ip_dst;
10.81 +
10.82 + //OLSR_PRINTF(3, "MDNS PLUGIN got packet from OLSR message\n");
10.83 +
10.84 +
10.85 + /* Check with each network interface what needs to be done on it */
10.86 + for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
10.87 + {
10.88 + /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
10.89 + if (walker->olsrIntf == NULL)
10.90 + {
10.91 + int nBytesWritten;
10.92 + struct sockaddr_ll dest;
10.93 +
10.94 + memset(&dest, 0, sizeof(dest));
10.95 + dest.sll_family = AF_PACKET;
10.96 + if ((encapsulationUdpData[0] & 0xf0) == 0x40) dest.sll_protocol = htons(ETH_P_IP);
10.97 + if ((encapsulationUdpData[0] & 0xf0) == 0x60) dest.sll_protocol = htons(ETH_P_IPV6);
10.98 + //TODO: if packet is not IP die here
10.99 + dest.sll_ifindex = if_nametoindex(walker->ifName);
10.100 + dest.sll_halen = IFHWADDRLEN;
10.101 +
10.102 + /* Use all-ones as destination MAC address. When the IP destination is
10.103 + * a multicast address, the destination MAC address should normally also
10.104 + * be a multicast address. E.g., when the destination IP is 224.0.0.1,
10.105 + * the destination MAC should be 01:00:5e:00:00:01. However, it does not
10.106 + * seem to matter when the destination MAC address is set to all-ones
10.107 + * in that case. */
10.108 + memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
10.109 +
10.110 + nBytesWritten = sendto(
10.111 + walker->capturingSkfd,
10.112 + encapsulationUdpData,
10.113 + len,
10.114 + 0,
10.115 + (struct sockaddr*) &dest,
10.116 + sizeof(dest));
10.117 + if (nBytesWritten != len)
10.118 + {
10.119 + BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
10.120 + }
10.121 + else
10.122 + {
10.123 +
10.124 + //OLSR_PRINTF(
10.125 + // 2,
10.126 + // "%s: --> unpacked and forwarded on \"%s\"\n",
10.127 + // PLUGIN_NAME_SHORT,
10.128 + // walker->ifName);
10.129 + }
10.130 + } /* if (walker->olsrIntf == NULL) */
10.131 +}
10.132 +} /* PacketReceivedFromOLSR */
10.133 +
10.134 +
10.135 +
10.136 +bool
10.137 +olsr_parser(union olsr_message *m,
10.138 + struct interface *in_if __attribute__((unused)),
10.139 + union olsr_ip_addr *ipaddr)
10.140 +{
10.141 + union olsr_ip_addr originator;
10.142 + int size;
10.143 + olsr_reltime vtime;
10.144 + //OLSR_PRINTF(2, "MDNS PLUGIN: Received msg in parser\n");
10.145 + /* Fetch the originator of the messsage */
10.146 + if(olsr_cnf->ip_version == AF_INET) {
10.147 + memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
10.148 + vtime = me_to_reltime(m->v4.olsr_vtime);
10.149 + size = ntohs(m->v4.olsr_msgsize);
10.150 + } else {
10.151 + memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
10.152 + vtime = me_to_reltime(m->v6.olsr_vtime);
10.153 + size = ntohs(m->v6.olsr_msgsize);
10.154 + }
10.155 +
10.156 + /* Check if message originated from this node.
10.157 + * If so - back off */
10.158 + if(olsr_ipcmp(&originator, &olsr_cnf->router_id) == 0)
10.159 + return false;
10.160 +
10.161 + /* Check that the neighbor this message was received from is symmetric.
10.162 + * If not - back off*/
10.163 + if(check_neighbor_link(ipaddr) != SYM_LINK) {
10.164 + //struct ipaddr_str strbuf;
10.165 + //OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
10.166 + return false;
10.167 + }
10.168 +
10.169 + if(olsr_cnf->ip_version == AF_INET){
10.170 + PacketReceivedFromOLSR((unsigned char*) &m->v4.message,size-12);
10.171 + }
10.172 + else {
10.173 + PacketReceivedFromOLSR((unsigned char*) &m->v6.message,size-12-96);
10.174 + }
10.175 + /* Forward the message */
10.176 + return true;
10.177 +}
10.178 +
10.179 +//Sends a packet in the OLSR network
10.180 +void
10.181 +olsr_mdns_gen(unsigned char* packet, int len)
10.182 +{
10.183 + /* send buffer: huge */
10.184 + char buffer[10240];
10.185 + union olsr_message *message = (union olsr_message *)buffer;
10.186 + struct interface *ifn;
10.187 + //int namesize;
10.188 +
10.189 + /* fill message */
10.190 + if(olsr_cnf->ip_version == AF_INET)
10.191 + {
10.192 + /* IPv4 */
10.193 + message->v4.olsr_msgtype = MESSAGE_TYPE;
10.194 + message->v4.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
10.195 + memcpy(&message->v4.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
10.196 + message->v4.ttl = MAX_TTL;
10.197 + message->v4.hopcnt = 0;
10.198 + message->v4.seqno = htons(get_msg_seqno());
10.199 +
10.200 + message->v4.olsr_msgsize = htons(len+12);
10.201 +
10.202 + memcpy(&message->v4.message,packet,len);
10.203 + len=len+12;
10.204 + }
10.205 + else
10.206 + {
10.207 + /* IPv6 */
10.208 + message->v6.olsr_msgtype = MESSAGE_TYPE;
10.209 + message->v6.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
10.210 + memcpy(&message->v6.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
10.211 + message->v6.ttl = MAX_TTL;
10.212 + message->v6.hopcnt = 0;
10.213 + message->v6.seqno = htons(get_msg_seqno());
10.214 +
10.215 + message->v6.olsr_msgsize = htons(len+12+96);
10.216 + memcpy(&message->v6.message,packet,len);
10.217 + len=len+12+96;
10.218 + }
10.219 +
10.220 + /* looping trough interfaces */
10.221 + OLSR_FOR_ALL_INTERFACES(ifn) {
10.222 + //OLSR_PRINTF(1, "MDNS PLUGIN: Generating packet - [%s]\n", ifn->int_name);
10.223 +
10.224 + if(net_outbuffer_push(ifn, message, len) != len) {
10.225 + /* send data and try again */
10.226 + net_output(ifn);
10.227 + if(net_outbuffer_push(ifn, message, len) != len) {
10.228 + //OLSR_PRINTF(1, "MDNS PLUGIN: could not send on interface: %s\n", ifn->int_name);
10.229 + }
10.230 + }
10.231 + } OLSR_FOR_ALL_INTERFACES_END(ifn);
10.232 +}
10.233 +
10.234 +/* -------------------------------------------------------------------------
10.235 + * Function : BmfPError
10.236 + * Description: Prints an error message at OLSR debug level 1.
10.237 + * First the plug-in name is printed. Then (if format is not NULL
10.238 + * and *format is not empty) the arguments are printed, followed
10.239 + * by a colon and a blank. Then the message and a new-line.
10.240 + * Input : format, arguments
10.241 + * Output : none
10.242 + * Return : none
10.243 + * Data Used : none
10.244 + * ------------------------------------------------------------------------- */
10.245 +
10.246 +void BmfPError(const char* format, ...)
10.247 +{
10.248 +#define MAX_STR_DESC 255
10.249 +#ifndef NODEBUG
10.250 + //char* strErr = strerror(errno);
10.251 +#endif
10.252 + char strDesc[MAX_STR_DESC];
10.253 +
10.254 + /* Rely on short-circuit boolean evaluation */
10.255 + if (format == NULL || *format == '\0')
10.256 + {
10.257 + //OLSR_PRINTF(1, "%s: %s\n", PLUGIN_NAME, strErr);
10.258 + }
10.259 + else
10.260 + {
10.261 + va_list arglist;
10.262 +
10.263 + //OLSR_PRINTF(1, "%s: ", PLUGIN_NAME);
10.264 +
10.265 + va_start(arglist, format);
10.266 + vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
10.267 + va_end(arglist);
10.268 +
10.269 + strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
10.270 +
10.271 + //OLSR_PRINTF(1, "%s: %s\n", strDesc, strErr);
10.272 + }
10.273 +} /* BmfPError */
10.274 +
10.275 +/* -------------------------------------------------------------------------
10.276 + * Function : MainAddressOf
10.277 + * Description: Lookup the main address of a node
10.278 + * Input : ip - IP address of the node
10.279 + * Output : none
10.280 + * Return : The main IP address of the node
10.281 + * Data Used : none
10.282 + * ------------------------------------------------------------------------- */
10.283 +union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip)
10.284 +{
10.285 + union olsr_ip_addr* result;
10.286 +
10.287 + /* TODO: mid_lookup_main_addr() is not thread-safe! */
10.288 + result = olsr_lookup_main_addr_by_alias(ip);
10.289 + if (result == NULL)
10.290 + {
10.291 + result = ip;
10.292 + }
10.293 + return result;
10.294 +} /* MainAddressOf */
10.295 +
10.296 +
10.297 +/* -------------------------------------------------------------------------
10.298 + * Function : BmfPacketCaptured
10.299 + * Description: Handle a captured IP packet
10.300 + * Input : intf - the network interface on which the packet was captured
10.301 + * sllPkttype - the type of packet. Either PACKET_OUTGOING,
10.302 + * PACKET_BROADCAST or PACKET_MULTICAST.
10.303 + * encapsulationUdpData - space for the encapsulation header, followed by
10.304 + * the captured IP packet
10.305 + * Output : none
10.306 + * Return : none
10.307 + * Data Used : BmfInterfaces
10.308 + * Notes : The IP packet is assumed to be captured on a socket of family
10.309 + * PF_PACKET and type SOCK_DGRAM (cooked).
10.310 + * ------------------------------------------------------------------------- */
10.311 +static void BmfPacketCaptured(
10.312 + //struct TBmfInterface* intf,
10.313 + //unsigned char sllPkttype,
10.314 + unsigned char* encapsulationUdpData,
10.315 + int nBytes)
10.316 +{
10.317 + union olsr_ip_addr src; /* Source IP address in captured packet */
10.318 + union olsr_ip_addr dst; /* Destination IP address in captured packet */
10.319 + union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */
10.320 + struct ip* ipHeader; /* The IP header inside the captured IP packet */
10.321 + struct ip6_hdr* ipHeader6; /* The IP header inside the captured IP packet */
10.322 + struct udphdr* udpHeader;
10.323 + u_int16_t destPort;
10.324 +
10.325 + if ((encapsulationUdpData[0] & 0xf0) == 0x40) { //IPV4
10.326 +
10.327 + ipHeader = (struct ip*) encapsulationUdpData;
10.328 +
10.329 + dst.v4 = ipHeader->ip_dst;
10.330 +
10.331 + /* Only forward multicast packets. If configured, also forward local broadcast packets */
10.332 + if (IsMulticast(&dst))
10.333 + {
10.334 + /* continue */
10.335 + }
10.336 + else
10.337 + {
10.338 + return;
10.339 + }
10.340 + if (ipHeader->ip_p != SOL_UDP)
10.341 + {
10.342 + /* Not UDP */
10.343 + //OLSR_PRINTF(1,"NON UDP PACKET\n");
10.344 + return; /* for */
10.345 + }
10.346 + udpHeader = (struct udphdr*)(encapsulationUdpData + GetIpHeaderLength(encapsulationUdpData));
10.347 + destPort = ntohs(udpHeader->dest);
10.348 + if (destPort != 5353)
10.349 + {
10.350 + return;
10.351 + }
10.352 + }//END IPV4
10.353 +
10.354 + else if ((encapsulationUdpData[0] & 0xf0) == 0x60) { //IPv6
10.355 +
10.356 + ipHeader6 = (struct ip6_hdr*) encapsulationUdpData;
10.357 + if (ipHeader6->ip6_dst.s6_addr[0] == 0xff) //Multicast
10.358 + {
10.359 + //Continua
10.360 + }
10.361 + else
10.362 + {
10.363 + return; //not multicast
10.364 + }
10.365 + if (ipHeader6->ip6_nxt != SOL_UDP)
10.366 + {
10.367 + /* Not UDP */
10.368 + //OLSR_PRINTF(1,"NON UDP PACKET\n");
10.369 + return; /* for */
10.370 + }
10.371 + udpHeader = (struct udphdr*)(encapsulationUdpData + 40);
10.372 + destPort = ntohs(udpHeader->dest);
10.373 + if (destPort != 5353)
10.374 + {
10.375 + return;
10.376 + }
10.377 + } //END IPV6
10.378 + else return; //Is not IP packet
10.379 +
10.380 + /* Check if the frame is captured on an OLSR-enabled interface */
10.381 + //isFromOlsrIntf = (intf->olsrIntf != NULL); TODO: put again this check
10.382 +
10.383 +
10.384 + /* Lookup main address of source in the MID table of OLSR */
10.385 + origIp = MainAddressOf(&src);
10.386 +
10.387 + // send the packet to OLSR forward mechanism
10.388 + olsr_mdns_gen(encapsulationUdpData,nBytes);
10.389 +} /* BmfPacketCaptured */
10.390 +
10.391 +
10.392 +/* -------------------------------------------------------------------------
10.393 + * Function : DoMDNS
10.394 + * Description: This function is registered with the OLSR scheduler and called when something is captured
10.395 + * Input : none
10.396 + * Output : none
10.397 + * Return : none
10.398 + * Data Used :
10.399 + * ------------------------------------------------------------------------- */
10.400 +void DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
10.401 +
10.402 +{
10.403 + unsigned char rxBuffer[BMF_BUFFER_SIZE];
10.404 + if (skfd >= 0)
10.405 + {
10.406 + struct sockaddr_ll pktAddr;
10.407 + socklen_t addrLen = sizeof(pktAddr);
10.408 + int nBytes;
10.409 + unsigned char* ipPacket;
10.410 +
10.411 + /* Receive the captured Ethernet frame, leaving space for the BMF
10.412 + * encapsulation header */
10.413 + ipPacket = GetIpPacket(rxBuffer);
10.414 + nBytes = recvfrom(
10.415 + skfd,
10.416 + ipPacket,
10.417 + BMF_BUFFER_SIZE, //TODO: understand how to change this
10.418 + 0,
10.419 + (struct sockaddr*)&pktAddr,
10.420 + &addrLen);
10.421 + if (nBytes < 0)
10.422 + {
10.423 +
10.424 + return; /* for */
10.425 + } /* if (nBytes < 0) */
10.426 +
10.427 + /* Check if the number of received bytes is large enough for an IP
10.428 + * packet which contains at least a minimum-size IP header.
10.429 + * Note: There is an apparent bug in the packet socket implementation in
10.430 + * combination with VLAN interfaces. On a VLAN interface, the value returned
10.431 + * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
10.432 + * returned on a non-VLAN interface, for the same ethernet frame. */
10.433 + if (nBytes < (int)sizeof(struct ip))
10.434 + {
10.435 + ////OLSR_PRINTF(
10.436 + // 1,
10.437 + // "%s: captured frame too short (%d bytes) on \"%s\"\n",
10.438 + // PLUGIN_NAME,
10.439 + // nBytes,
10.440 + // walker->ifName);
10.441 +
10.442 + return; /* for */
10.443 + }
10.444 +
10.445 + if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
10.446 + pktAddr.sll_pkttype == PACKET_MULTICAST ||
10.447 + pktAddr.sll_pkttype == PACKET_BROADCAST)
10.448 + {
10.449 + /* A multicast or broadcast packet was captured */
10.450 +
10.451 + ////OLSR_PRINTF(
10.452 + // 1,
10.453 + // "%s: captured frame (%d bytes) on \"%s\"\n",
10.454 + // PLUGIN_NAME,
10.455 + // nBytes,
10.456 + // walker->ifName);
10.457 + //BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);
10.458 + BmfPacketCaptured(ipPacket,nBytes);
10.459 +
10.460 + } /* if (pktAddr.sll_pkttype == ...) */
10.461 + } /* if (skfd >= 0 && (FD_ISSET...)) */
10.462 +} /* DoMDNS */
10.463 +
10.464 +int InitMDNS(struct interface* skipThisIntf)
10.465 +{
10.466 +
10.467 +
10.468 + //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
10.469 + olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
10.470 + //Creates captures sockets and register them to the OLSR scheduler
10.471 + CreateBmfNetworkInterfaces(skipThisIntf);
10.472 +
10.473 + return 0;
10.474 +} /* InitMDNS */
10.475 +
10.476 +/* -------------------------------------------------------------------------
10.477 + * Function : CloseMDNS
10.478 + * Description: Close the MDNS plugin and clean up
10.479 + * Input : none
10.480 + * Output : none
10.481 + * Return : none
10.482 + * Data Used :
10.483 + * ------------------------------------------------------------------------- */
10.484 +void CloseMDNS(void)
10.485 +{
10.486 + CloseBmfNetworkInterfaces();
10.487 +}
10.488 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/lib/mdns/src/mdns.h Thu Mar 26 01:25:34 2009 +0100
11.3 @@ -0,0 +1,79 @@
11.4 +/*
11.5 +OLSR MDNS plugin.
11.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
11.7 +
11.8 + This file is part of OLSR MDNS PLUGIN.
11.9 +
11.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
11.11 + it under the terms of the GNU General Public License as published by
11.12 + the Free Software Foundation, either version 3 of the License, or
11.13 + (at your option) any later version.
11.14 +
11.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
11.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.18 + GNU General Public License for more details.
11.19 +
11.20 + You should have received a copy of the GNU General Public License
11.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
11.22 +
11.23 +
11.24 + */
11.25 +
11.26 +
11.27 +#ifndef _MDNS_MDNS_H
11.28 +#define _MDNS_MDNS_H
11.29 +
11.30 +
11.31 +#include "plugin.h" /* union set_plugin_parameter_addon */
11.32 +
11.33 +#include "parser.h"
11.34 +
11.35 +#define MESSAGE_TYPE 132
11.36 +#define PARSER_TYPE MESSAGE_TYPE
11.37 +#define EMISSION_INTERVAL 10 /* seconds */
11.38 +#define EMISSION_JITTER 25 /* percent */
11.39 +#define MDNS_VALID_TIME 1800 /* seconds */
11.40 +
11.41 +/* BMF plugin data */
11.42 +#define PLUGIN_NAME "OLSRD MDNS plugin"
11.43 +#define PLUGIN_NAME_SHORT "OLSRD MDNS"
11.44 +#define PLUGIN_VERSION "1.0.0 (" __DATE__ " " __TIME__ ")"
11.45 +#define PLUGIN_COPYRIGHT " (C) Ninux.org"
11.46 +#define PLUGIN_AUTHOR " Saverio Proto (zioproto@gmail.com)"
11.47 +#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
11.48 +#define PLUGIN_INTERFACE_VERSION 5
11.49 +
11.50 +/* UDP-Port on which multicast packets are encapsulated */
11.51 +//#define BMF_ENCAP_PORT 50698
11.52 +
11.53 +/* Forward declaration of OLSR interface type */
11.54 +struct interface;
11.55 +
11.56 +//extern int FanOutLimit;
11.57 +//extern int BroadcastRetransmitCount;
11.58 +
11.59 +void DoMDNS(int sd, void * x, unsigned int y);
11.60 +void BmfPError(const char* format, ...) __attribute__((format(printf, 1, 2)));
11.61 +union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip);
11.62 +//int InterfaceChange(struct interface* interf, int action);
11.63 +//int SetFanOutLimit(const char* value, void* data, set_plugin_parameter_addon addon);
11.64 +//int InitBmf(struct interface* skipThisIntf);
11.65 +//void CloseBmf(void);
11.66 +int InitMDNS(struct interface* skipThisIntf);
11.67 +void CloseMDNS(void);
11.68 +
11.69 +void olsr_mdns_gen(unsigned char* packet, int len);
11.70 +
11.71 +/* Parser function to register with the scheduler */
11.72 +bool
11.73 +olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);
11.74 +
11.75 +#endif /* _MDNS_MDNS_H */
11.76 +
11.77 +/*
11.78 + * Local Variables:
11.79 + * c-basic-offset: 2
11.80 + * indent-tabs-mode: nil
11.81 + * End:
11.82 + */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/lib/mdns/src/olsrd_plugin.c Thu Mar 26 01:25:34 2009 +0100
12.3 @@ -0,0 +1,167 @@
12.4 +/*
12.5 +OLSR MDNS plugin.
12.6 +Written by Saverio Proto <zioproto@gmail.com> and Claudio Pisa <clauz@ninux.org>.
12.7 +
12.8 + This file is part of OLSR MDNS PLUGIN.
12.9 +
12.10 + The OLSR MDNS PLUGIN is free software: you can redistribute it and/or modify
12.11 + it under the terms of the GNU General Public License as published by
12.12 + the Free Software Foundation, either version 3 of the License, or
12.13 + (at your option) any later version.
12.14 +
12.15 + The OLSR MDNS PLUGIN is distributed in the hope that it will be useful,
12.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
12.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.18 + GNU General Public License for more details.
12.19 +
12.20 + You should have received a copy of the GNU General Public License
12.21 + along with Foobar. If not, see <http://www.gnu.org/licenses/>.
12.22 +
12.23 +
12.24 + */
12.25 +
12.26 +/* System includes */
12.27 +#include <assert.h> /* assert() */
12.28 +#include <stddef.h> /* NULL */
12.29 +
12.30 +/* OLSRD includes */
12.31 +#include "plugin.h"
12.32 +#include "plugin_util.h"
12.33 +#include "defs.h" /* uint8_t, olsr_cnf */
12.34 +#include "scheduler.h" /* olsr_start_timer() */
12.35 +#include "olsr_cfg.h" /* olsr_cnf() */
12.36 +#include "olsr_cookie.h" /* olsr_alloc_cookie() */
12.37 +
12.38 +/* BMF includes */
12.39 +#include "mdns.h" /* InitBmf(), CloseBmf() */
12.40 +#include "NetworkInterfaces.h" /* AddNonOlsrBmfIf(), SetBmfInterfaceIp(), ... */
12.41 +#include "Address.h" /* DoLocalBroadcast() */
12.42 +
12.43 +static void __attribute__ ((constructor)) my_init(void);
12.44 +static void __attribute__ ((destructor)) my_fini(void);
12.45 +
12.46 +//static struct olsr_cookie_info *prune_packet_history_timer_cookie;
12.47 +
12.48 +void olsr_plugin_exit(void);
12.49 +
12.50 +/* -------------------------------------------------------------------------
12.51 + * Function : olsrd_plugin_interface_version
12.52 + * Description: Plugin interface version
12.53 + * Input : none
12.54 + * Output : none
12.55 + * Return : BMF plugin interface version number
12.56 + * Data Used : none
12.57 + * Notes : Called by main OLSRD (olsr_load_dl) to check plugin interface
12.58 + * version
12.59 + * ------------------------------------------------------------------------- */
12.60 +int olsrd_plugin_interface_version(void)
12.61 +{
12.62 + return PLUGIN_INTERFACE_VERSION;
12.63 +}
12.64 +
12.65 +/* -------------------------------------------------------------------------
12.66 + * Function : olsrd_plugin_init
12.67 + * Description: Plugin initialisation
12.68 + * Input : none
12.69 + * Output : none
12.70 + * Return : fail (0) or success (1)
12.71 + * Data Used : olsr_cnf
12.72 + * Notes : Called by main OLSRD (init_olsr_plugin) to initialize plugin
12.73 + * ------------------------------------------------------------------------- */
12.74 +int olsrd_plugin_init(void)
12.75 +{
12.76 + /* Clear the packet history */
12.77 + //InitPacketHistory();
12.78 +
12.79 + /* Register ifchange function */
12.80 + //add_ifchgf(&InterfaceChange);
12.81 +
12.82 + /* create the cookie */
12.83 + //prune_packet_history_timer_cookie = olsr_alloc_cookie("BMF: Prune Packet History", OLSR_COOKIE_TYPE_TIMER);
12.84 +
12.85 + /* Register the duplicate registration pruning process */
12.86 + //olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
12.87 + // &PrunePacketHistory, NULL, prune_packet_history_timer_cookie->ci_id);
12.88 +
12.89 +
12.90 + return InitMDNS(NULL);
12.91 +}
12.92 +
12.93 +/* -------------------------------------------------------------------------
12.94 + * Function : olsr_plugin_exit
12.95 + * Description: Plugin cleanup
12.96 + * Input : none
12.97 + * Output : none
12.98 + * Return : none
12.99 + * Data Used : none
12.100 + * Notes : Called by my_fini() at unload of shared object
12.101 + * ------------------------------------------------------------------------- */
12.102 +void olsr_plugin_exit(void)
12.103 +{
12.104 + CloseMDNS();
12.105 +}
12.106 +
12.107 +static const struct olsrd_plugin_parameters plugin_parameters[] = {
12.108 + { .name = "NonOlsrIf", .set_plugin_parameter = &AddNonOlsrBmfIf, .data = NULL },
12.109 + //{ .name = "DoLocalBroadcast", .set_plugin_parameter = &DoLocalBroadcast, .data = NULL },
12.110 + //{ .name = "BmfInterface", .set_plugin_parameter = &SetBmfInterfaceName, .data = NULL },
12.111 + //{ .name = "BmfInterfaceIp", .set_plugin_parameter = &SetBmfInterfaceIp, .data = NULL },
12.112 + //{ .name = "CapturePacketsOnOlsrInterfaces", .set_plugin_parameter = &SetCapturePacketsOnOlsrInterfaces, .data = NULL },
12.113 + //{ .name = "BmfMechanism", .set_plugin_parameter = &SetBmfMechanism, .data = NULL },
12.114 + //{ .name = "FanOutLimit", .set_plugin_parameter = &SetFanOutLimit, .data = NULL },
12.115 + //{ .name = "BroadcastRetransmitCount", .set_plugin_parameter = &set_plugin_int, .data = &BroadcastRetransmitCount},
12.116 +};
12.117 +
12.118 +/* -------------------------------------------------------------------------
12.119 + * Function : olsrd_get_plugin_parameters
12.120 + * Description: Return the parameter table and its size
12.121 + * Input : none
12.122 + * Output : params - the parameter table
12.123 + * size - its size in no. of entries
12.124 + * Return : none
12.125 + * Data Used : plugin_parameters
12.126 + * Notes : Called by main OLSR (init_olsr_plugin) for all plugins
12.127 + * ------------------------------------------------------------------------- */
12.128 +void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
12.129 +{
12.130 + *params = plugin_parameters;
12.131 + *size = ARRAYSIZE(plugin_parameters);
12.132 +}
12.133 +
12.134 +/* -------------------------------------------------------------------------
12.135 + * Function : my_init
12.136 + * Description: Plugin constructor
12.137 + * Input : none
12.138 + * Output : none
12.139 + * Return : none
12.140 + * Data Used : none
12.141 + * Notes : Called at load of shared object
12.142 + * ------------------------------------------------------------------------- */
12.143 +static void my_init(void)
12.144 +{
12.145 + /* Print plugin info to stdout */
12.146 + printf("%s\n", MOD_DESC);
12.147 +
12.148 + return;
12.149 +}
12.150 +
12.151 +/* -------------------------------------------------------------------------
12.152 + * Function : my_fini
12.153 + * Description: Plugin destructor
12.154 + * Input : none
12.155 + * Output : none
12.156 + * Return : none
12.157 + * Data Used : none
12.158 + * Notes : Called at unload of shared object
12.159 + * ------------------------------------------------------------------------- */
12.160 +static void my_fini(void)
12.161 +{
12.162 + olsr_plugin_exit();
12.163 +}
12.164 +
12.165 +/*
12.166 + * Local Variables:
12.167 + * c-basic-offset: 2
12.168 + * indent-tabs-mode: nil
12.169 + * End:
12.170 + */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/lib/mdns/version-script.txt Thu Mar 26 01:25:34 2009 +0100
13.3 @@ -0,0 +1,10 @@
13.4 +VERS_1.0
13.5 +{
13.6 + global:
13.7 + olsrd_plugin_interface_version;
13.8 + olsrd_plugin_init;
13.9 + olsrd_get_plugin_parameters;
13.10 +
13.11 + local:
13.12 + *;
13.13 +};