e4979b9906b45547196b704dbf7b5c1a1e0ac2d6
[olsrd.git] / lib / mdns / src / mdns.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41
42 #include "mdns.h"
43
44 /* System includes */
45 #include <stddef.h>             /* NULL */
46 #include <sys/types.h>          /* ssize_t */
47 #include <string.h>             /* strerror() */
48 #include <stdarg.h>             /* va_list, va_start, va_end */
49 #include <errno.h>              /* errno */
50 #include <assert.h>             /* assert() */
51 #include <linux/if_ether.h>     /* ETH_P_IP */
52 #include <linux/if_packet.h>    /* struct sockaddr_ll, PACKET_MULTICAST */
53 //#include <pthread.h> /* pthread_t, pthread_create() */
54 #include <signal.h>             /* sigset_t, sigfillset(), sigdelset(), SIGINT */
55 #include <netinet/ip.h>         /* struct ip */
56 #include <netinet/udp.h>        /* struct udphdr */
57 #include <unistd.h>             /* close() */
58
59 #include <netinet/in.h>
60 #include <netinet/ip6.h>
61
62 /* OLSRD includes */
63 #include "plugin_util.h"        /* set_plugin_int */
64 #include "defs.h"               /* olsr_cnf, //OLSR_PRINTF */
65 #include "ipcalc.h"
66 #include "olsr.h"               /* //OLSR_PRINTF */
67 #include "mid_set.h"            /* mid_lookup_main_addr() */
68 #include "link_set.h"           /* get_best_link_to_neighbor() */
69 #include "net_olsr.h"           /* ipequal */
70
71 /* plugin includes */
72 #include "NetworkInterfaces.h"  /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
73 #include "Address.h"            /* IsMulticast() */
74 #include "Packet.h"             /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
75 #include "list_backport.h"
76 #include "RouterElection.h"
77 #include "list_backport.h"
78
79 #define OLSR_FOR_ALL_FILTEREDNODES_ENTRIES(n, iterator) listbackport_for_each_element_safe(&ListOfFilteredHosts, n, list, iterator)
80
81 struct list_entity ListOfFilteredHosts;
82 int FHListInit = 0;
83
84 /* -------------------------------------------------------------------------
85  * Function   : PacketReceivedFromOLSR
86  * Description: Handle a received packet from a OLSR message
87  * Input      : ipPacket into an unsigned char and the lenght of the packet
88  * Output     : none
89  * Return     : none
90  * Data Used  : BmfInterfaces
91  * ------------------------------------------------------------------------- */
92 static void
93 PacketReceivedFromOLSR(unsigned char *encapsulationUdpData, int len)
94 {
95   struct ip *ipHeader;                 /* IP header inside the encapsulated IP packet */
96   struct ip6_hdr *ip6Header;                 /* IP header inside the encapsulated IP packet */
97   //union olsr_ip_addr mcSrc;            /* Original source of the encapsulated multicast packet */
98   //union olsr_ip_addr mcDst;            /* Multicast destination of the encapsulated packet */
99   struct TBmfInterface *walker;
100   int stripped_len = 0;
101   ipHeader = (struct ip *)ARM_NOWARN_ALIGN(encapsulationUdpData);
102   ip6Header = (struct ip6_hdr *)ARM_NOWARN_ALIGN(encapsulationUdpData);
103
104   //mcSrc.v4 = ipHeader->ip_src;
105   //mcDst.v4 = ipHeader->ip_dst;
106   //OLSR_DEBUG(LOG_PLUGINS, "MDNS PLUGIN got packet from OLSR message\n");
107
108
109   /* Check with each network interface what needs to be done on it */
110   for (walker = BmfInterfaces; walker != NULL; walker = walker->next) {
111     /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
112     if (walker->olsrIntf == NULL) {
113       int nBytesWritten;
114       struct sockaddr_ll dest;
115
116       memset(&dest, 0, sizeof(dest));
117       dest.sll_family = AF_PACKET;
118       if ((encapsulationUdpData[0] & 0xf0) == 0x40) {
119         dest.sll_protocol = htons(ETH_P_IP);
120         stripped_len = ntohs(ipHeader->ip_len);
121         if(my_TTL_Check)
122                 ipHeader->ip_ttl = (u_int8_t) 1; //setting up TTL to 1 to avoid mdns packets flood 
123         }
124       if ((encapsulationUdpData[0] & 0xf0) == 0x60) {
125         dest.sll_protocol = htons(ETH_P_IPV6);
126         stripped_len = 40 + ntohs(ip6Header->ip6_plen); //IPv6 Header size (40) + payload_len 
127         if(my_TTL_Check)
128                 ip6Header->ip6_hops = (uint8_t) 1; //setting up Hop Limit to 1 to avoid mdns packets flood
129         }
130       // Sven-Ola: Don't know how to handle the "stripped_len is uninitialized" condition, maybe exit(1) is better...?
131       if (0 == stripped_len) return;
132       //TODO: if packet is not IP die here
133       
134       if (stripped_len > len) {
135         //OLSR_DEBUG(LOG_PLUGINS, "MDNS: Stripped len bigger than len ??\n");
136         }
137       dest.sll_ifindex = if_nametoindex(walker->ifName);
138       dest.sll_halen = IFHWADDRLEN;
139
140       /* Use all-ones as destination MAC address. When the IP destination is
141        * a multicast address, the destination MAC address should normally also
142        * be a multicast address. E.g., when the destination IP is 224.0.0.1,
143        * the destination MAC should be 01:00:5e:00:00:01. However, it does not
144        * seem to matter when the destination MAC address is set to all-ones
145        * in that case. */
146       memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
147       
148       if(walker->isActive == 0)             //Don't forward packet if isn't master router
149         return;
150
151       nBytesWritten = sendto(walker->capturingSkfd, encapsulationUdpData, stripped_len, 0, (struct sockaddr *)&dest, sizeof(dest));
152       if (nBytesWritten != stripped_len) {
153         BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
154       } else {
155
156         //OLSR_PRINTF(
157         //  2,
158         //  "%s: --> unpacked and forwarded on \"%s\"\n",
159         //  PLUGIN_NAME_SHORT,
160         //  walker->ifName);
161       }
162     }                           /* if (walker->olsrIntf == NULL) */
163   }
164 }                               /* PacketReceivedFromOLSR */
165
166
167 bool
168 olsr_parser(union olsr_message *m, struct interface *in_if __attribute__ ((unused)), union olsr_ip_addr *ipaddr)
169 {
170   union olsr_ip_addr originator;
171   int size;
172   //OLSR_DEBUG(LOG_PLUGINS, "MDNS PLUGIN: Received msg in parser\n");
173   /* Fetch the originator of the messsage */
174   if (olsr_cnf->ip_version == AF_INET) {
175     memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
176     size = ntohs(m->v4.olsr_msgsize);
177   } else {
178     memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
179     size = ntohs(m->v6.olsr_msgsize);
180   }
181
182   /* Check if message originated from this node.
183    *         If so - back off */
184   if (ipequal(&originator, &olsr_cnf->main_addr))
185     return false;
186
187   /* Check that the neighbor this message was received from is symmetric.
188    *         If not - back off*/
189   if (check_neighbor_link(ipaddr) != SYM_LINK) {
190     //struct ipaddr_str strbuf;
191     //OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
192     return false;
193   }
194
195   if (olsr_cnf->ip_version == AF_INET) {
196     PacketReceivedFromOLSR((unsigned char *)&m->v4.message, size - 12);
197   } else {
198     PacketReceivedFromOLSR((unsigned char *)&m->v6.message, size - 12 - 96);
199   }
200 //forward the message
201 return true;
202 }
203
204 //Sends a packet in the OLSR network
205 void
206 olsr_mdns_gen(unsigned char *packet, int len)
207 {
208   /* send buffer: huge */
209   char buffer[10240];
210   int aligned_size;
211   union olsr_message *message = (union olsr_message *)buffer;
212   struct interface *ifn;
213   
214   aligned_size=len;
215
216 if ((aligned_size % 4) != 0) {
217     aligned_size = (aligned_size - (aligned_size % 4)) + 4;
218   }
219
220   /* fill message */
221   if (olsr_cnf->ip_version == AF_INET) {
222     /* IPv4 */
223     message->v4.olsr_msgtype = MESSAGE_TYPE;
224     message->v4.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
225     memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
226     //message->v4.ttl = MAX_TTL;
227     if (my_MDNS_TTL) message->v4.ttl = my_MDNS_TTL;
228     else message->v4.ttl = MAX_TTL;
229     message->v4.hopcnt = 0;
230     message->v4.seqno = htons(get_msg_seqno());
231
232     message->v4.olsr_msgsize = htons(aligned_size + 12);
233
234     memset(&message->v4.message, 0, aligned_size);
235     memcpy(&message->v4.message, packet, len);
236     aligned_size = aligned_size + 12;
237   } else {
238     /* IPv6 */
239     message->v6.olsr_msgtype = MESSAGE_TYPE;
240     message->v6.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
241     memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
242     //message->v6.ttl = MAX_TTL;
243     if (my_MDNS_TTL) message->v6.ttl = my_MDNS_TTL;
244     else message->v6.ttl = MAX_TTL;
245     message->v6.hopcnt = 0;
246     message->v6.seqno = htons(get_msg_seqno());
247
248     message->v6.olsr_msgsize = htons(aligned_size + 12 + 96);
249     memset(&message->v6.message, 0, aligned_size);
250     memcpy(&message->v6.message, packet, len);
251     aligned_size = aligned_size + 12 + 96;
252   }
253
254   /* looping trough interfaces */
255  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
256     //OLSR_PRINTF(1, "MDNS PLUGIN: Generating packet - [%s]\n", ifn->int_name);
257
258     if (net_outbuffer_push(ifn, message, aligned_size) != aligned_size) {
259       /* send data and try again */
260       net_output(ifn);
261       if (net_outbuffer_push(ifn, message, aligned_size) != aligned_size) {
262         //OLSR_PRINTF(1, "MDNS PLUGIN: could not send on interface: %s\n", ifn->int_name);
263       }
264     }
265   }
266 }
267
268 /* -------------------------------------------------------------------------
269  * Function   : BmfPError
270  * Description: Prints an error message at OLSR debug level 1.
271  *              First the plug-in name is printed. Then (if format is not NULL
272  *              and *format is not empty) the arguments are printed, followed
273  *              by a colon and a blank. Then the message and a new-line.
274  * Input      : format, arguments
275  * Output     : none
276  * Return     : none
277  * Data Used  : none
278  * ------------------------------------------------------------------------- */
279
280 void
281 BmfPError(const char *format, ...)
282 {
283 #define MAX_STR_DESC 255
284   char strDesc[MAX_STR_DESC];
285
286 #if !defined REMOVE_LOG_DEBUG
287   //char *stringErr = strerror(errno);
288 #endif
289   /* Rely on short-circuit boolean evaluation */
290   if (format == NULL || *format == '\0') {
291     //OLSR_DEBUG(LOG_PLUGINS, "%s: %s\n", PLUGIN_NAME, stringErr);
292   } else {
293     va_list arglist;
294
295     va_start(arglist, format);
296     vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
297     va_end(arglist);
298
299     strDesc[MAX_STR_DESC - 1] = '\0';   /* Ensures null termination */
300
301     //OLSR_DEBUG(LOG_PLUGINS, "%s: %s\n", strDesc, stringErr);
302   }
303 }                               /* BmfPError */
304
305 /* -------------------------------------------------------------------------
306  * Function   : MainAddressOf
307  * Description: Lookup the main address of a node
308  * Input      : ip - IP address of the node
309  * Output     : none
310  * Return     : The main IP address of the node
311  * Data Used  : none
312  * ------------------------------------------------------------------------- */
313 union olsr_ip_addr *
314 MainAddressOf(union olsr_ip_addr *ip)
315 {
316   union olsr_ip_addr *result;
317
318   /* TODO: mid_lookup_main_addr() is not thread-safe! */
319   result = mid_lookup_main_addr(ip);
320   if (result == NULL) {
321     result = ip;
322   }
323   return result;
324 }                               /* MainAddressOf */
325
326 int
327 AddFilteredHost(const char *FilteredHost, void *data __attribute__ ((unused)), 
328                 set_plugin_parameter_addon addon __attribute__ ((unused))){
329
330   int res = 0;
331   struct FilteredHost *tmp;
332   tmp = (struct FilteredHost *) malloc(sizeof(struct FilteredHost));
333   listbackport_init_node(&tmp->list);
334
335   if(FHListInit == 0){
336     listbackport_init_head(&ListOfFilteredHosts);
337     FHListInit = 1;
338   }
339
340   if(olsr_cnf->ip_version == AF_INET){
341     res = inet_pton(AF_INET, FilteredHost, &tmp->host.v4);
342     if(res > 0){
343       listbackport_add_tail(&ListOfFilteredHosts, &tmp->list);
344     }
345     else
346       free(tmp);
347   }
348   else{
349     res = inet_pton(AF_INET6, FilteredHost, &tmp->host.v6);
350     if(res > 0)
351       listbackport_add_tail(&ListOfFilteredHosts, &tmp->list);
352     else
353       free(tmp);
354   }
355
356   return 0;
357 }
358
359 int
360 isInFilteredList(union olsr_ip_addr *src){//TODO: implement here check if IP is in filtered list
361
362   struct FilteredHost *tmp, *iterator;
363   
364   if(FHListInit == 0){
365     listbackport_init_head(&ListOfFilteredHosts);
366     FHListInit = 1;
367   }
368
369
370   if(listbackport_is_empty(&ListOfFilteredHosts))
371     return 0;
372
373   OLSR_FOR_ALL_FILTEREDNODES_ENTRIES(tmp, iterator){
374     if(olsr_cnf->ip_version == AF_INET){
375       if(memcmp(&tmp->host.v4, &src->v4, sizeof(struct in_addr)) == 0)
376         return 1;
377     }
378     else{
379       if(memcmp(&tmp->host.v6, &src->v6, sizeof(struct in6_addr)) == 0)
380         return 1;
381     }
382   }
383
384   return 0;
385 }
386
387 /* -------------------------------------------------------------------------
388  * Function   : BmfPacketCaptured
389  * Description: Handle a captured IP packet
390  * Input      : intf - the network interface on which the packet was captured
391  *              sllPkttype - the type of packet. Either PACKET_OUTGOING,
392  *                PACKET_BROADCAST or PACKET_MULTICAST.
393  *              encapsulationUdpData - space for the encapsulation header, followed by
394  *                the captured IP packet
395  * Output     : none
396  * Return     : none
397  * Data Used  : BmfInterfaces
398  * Notes      : The IP packet is assumed to be captured on a socket of family
399  *              PF_PACKET and type SOCK_DGRAM (cooked).
400  * ------------------------------------------------------------------------- */
401 static void
402 BmfPacketCaptured(
403                    //struct TBmfInterface* intf,
404                    //unsigned char sllPkttype,
405                    unsigned char *encapsulationUdpData, int nBytes)
406 {
407   union olsr_ip_addr dst;              /* Destination IP address in captured packet */
408   union olsr_ip_addr src;              
409   struct ip *ipHeader;                 /* The IP header inside the captured IP packet */
410   struct ip6_hdr *ipHeader6;           /* The IP header inside the captured IP packet */
411   struct udphdr *udpHeader;
412   u_int16_t destPort;
413
414   if ((encapsulationUdpData[0] & 0xf0) == 0x40) {       //IPV4
415
416     ipHeader = (struct ip *)ARM_NOWARN_ALIGN(encapsulationUdpData);
417
418     dst.v4 = ipHeader->ip_dst;
419     src.v4 = ipHeader->ip_src;
420
421     /* Only forward multicast packets. If configured, also forward local broadcast packets */
422     if (IsMulticast(&dst)) {
423       /* continue */
424     } else {
425       return;
426     }
427     if (ipHeader->ip_p != SOL_UDP) {
428       /* Not UDP */
429       //OLSR_PRINTF(1,"NON UDP PACKET\n");
430       return;                   /* for */
431     }
432     udpHeader = (struct udphdr *)ARM_NOWARN_ALIGN(encapsulationUdpData + GetIpHeaderLength(encapsulationUdpData));
433     destPort = ntohs(udpHeader->dest);
434     if (destPort != 5353) {
435       return;
436     }
437     if(my_TTL_Check)
438         if(((u_int8_t) ipHeader->ip_ttl) <= ((u_int8_t) 1))    // Discard mdns packet with TTL limit 1 or less
439                 return;
440
441     if (isInFilteredList(&src)) {
442       return;
443     }
444
445   }                             //END IPV4
446
447   else if ((encapsulationUdpData[0] & 0xf0) == 0x60) {  //IPv6
448
449     ipHeader6 = (struct ip6_hdr *)ARM_NOWARN_ALIGN(encapsulationUdpData);
450
451     //TODO: mettere dentro src.v6 l'indirizzo IPv6
452
453     if (ipHeader6->ip6_dst.s6_addr[0] == 0xff)  //Multicast
454     {
455       //Continua
456     } else {
457       return;                   //not multicast
458     }
459     if (ipHeader6->ip6_nxt != SOL_UDP) {
460       /* Not UDP */
461       //OLSR_PRINTF(1,"NON UDP PACKET\n");
462       return;                   /* for */
463     }
464     udpHeader = (struct udphdr *)ARM_NOWARN_ALIGN(encapsulationUdpData + 40);
465     destPort = ntohs(udpHeader->dest);
466     if (destPort != 5353) {
467       return;
468     }
469     if(my_TTL_Check)
470         if(((uint8_t) ipHeader6->ip6_hops) <= ((uint8_t) 1))  // Discard mdns packet with hop limit 1 or less
471                 return;
472   
473     if (isInFilteredList(&src)) {
474       return;
475     }
476
477   }                             //END IPV6
478   else
479     return;                     //Is not IP packet
480
481   /* Check if the frame is captured on an OLSR-enabled interface */
482   //isFromOlsrIntf = (intf->olsrIntf != NULL); TODO: put again this check
483
484   // send the packet to OLSR forward mechanism
485   olsr_mdns_gen(encapsulationUdpData, nBytes);
486 }                               /* BmfPacketCaptured */
487
488
489 /* -------------------------------------------------------------------------
490  * Function   : DoMDNS
491  * Description: This function is registered with the OLSR scheduler and called when something is captured
492  * Input      : none
493  * Output     : none
494  * Return     : none
495  * Data Used  :
496  * ------------------------------------------------------------------------- */
497 void
498 DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
499 {
500   unsigned char rxBuffer[BMF_BUFFER_SIZE];
501   if (skfd >= 0) {
502     struct sockaddr_ll pktAddr;
503     socklen_t addrLen = sizeof(pktAddr);
504     int nBytes;
505     unsigned char *ipPacket;
506     struct TBmfInterface *walker;
507
508     /* Receive the captured Ethernet frame, leaving space for the BMF
509      * encapsulation header */
510     ipPacket = GetIpPacket(rxBuffer);
511     nBytes = recvfrom(skfd, ipPacket, BMF_BUFFER_SIZE,  //TODO: understand how to change this
512                       0, (struct sockaddr *)&pktAddr, &addrLen);
513     if (nBytes < 0) {
514
515       return;                   /* for */
516     }
517
518     /* if (nBytes < 0) */
519     /* Check if the number of received bytes is large enough for an IP
520      * packet which contains at least a minimum-size IP header.
521      * Note: There is an apparent bug in the packet socket implementation in
522      * combination with VLAN interfaces. On a VLAN interface, the value returned
523      * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
524      * returned on a non-VLAN interface, for the same ethernet frame. */
525     if (nBytes < (int)sizeof(struct ip)) {
526       ////OLSR_PRINTF(
527       //              1,
528       //              "%s: captured frame too short (%d bytes) on \"%s\"\n",
529       //              PLUGIN_NAME,
530       //              nBytes,
531       //              walker->ifName);
532
533       return;                   /* for */
534     }
535
536     for(walker = BmfInterfaces; walker != NULL; walker = walker->next){ //if the router isn't the master for this interface
537       if(skfd == walker->capturingSkfd && walker->isActive == 0)        //discard mdns packets
538         return;
539     }
540
541     if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
542         pktAddr.sll_pkttype == PACKET_MULTICAST || pktAddr.sll_pkttype == PACKET_BROADCAST) {
543       /* A multicast or broadcast packet was captured */
544
545       ////OLSR_PRINTF(
546       //              1,
547       //              "%s: captured frame (%d bytes) on \"%s\"\n",
548       //              PLUGIN_NAME,
549       //              nBytes,
550       //              walker->ifName);
551       //BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);
552       BmfPacketCaptured(ipPacket, nBytes);
553
554     }                           /* if (pktAddr.sll_pkttype == ...) */
555   }                             /* if (skfd >= 0 && (FD_ISSET...)) */
556 }                               /* DoMDNS */
557
558 int
559 InitMDNS(struct interface *skipThisIntf)
560 {
561   //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
562   olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
563   //Creates captures sockets and register them to the OLSR scheduler
564   CreateBmfNetworkInterfaces(skipThisIntf);
565   InitRouterList(NULL);
566
567   return 1;
568 }                               /* InitMDNS */
569
570 /* -------------------------------------------------------------------------
571  * Function   : CloseMDNS
572  * Description: Close the MDNS plugin and clean up
573  * Input      : none
574  * Output     : none
575  * Return     : none
576  * Data Used  :
577  * ------------------------------------------------------------------------- */
578 void
579 CloseMDNS(void)
580 {
581   CloseBmfNetworkInterfaces();
582 }
583
584 void DoElection(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
585 {
586   static const char * rxBufferPrefix = "$REP";
587   static const ssize_t rxBufferPrefixLength = 4;
588   unsigned char rxBuffer[HELLO_BUFFER_SIZE];
589   ssize_t rxCount;
590   union olsr_sockaddr sender;
591   socklen_t senderSize = sizeof(sender);
592   struct RtElHelloPkt *rcvPkt;
593   struct RouterListEntry *listEntry;
594   struct RouterListEntry6 *listEntry6;
595
596   OLSR_PRINTF(1,"Packet Received \n");
597
598   if (skfd >= 0) {
599     memset(&sender, 0, senderSize);
600     rxCount = recvfrom(skfd, &rxBuffer[0], (sizeof(rxBuffer) - 1), 0,
601                 (struct sockaddr *)&sender, &senderSize);
602     if(rxCount < 0){
603       BmfPError("Receive error in %s, ignoring message.", __func__);
604       return;
605     }
606
607   /* make sure the string is null terminated */
608   rxBuffer[rxCount] = '\0';
609
610   /* do not process when this message doesn't start with $REP */
611   if ((rxCount < rxBufferPrefixLength) || (strncmp((char *) rxBuffer,
612                   rxBufferPrefix, rxBufferPrefixLength) != 0))
613     return;
614
615   if ( rxCount < (int)sizeof(struct RtElHelloPkt))
616     return;                                     // too small to be a hello pkt
617   else
618     rcvPkt = (struct RtElHelloPkt *)ARM_NOWARN_ALIGN(rxBuffer);
619
620   if (rcvPkt->ipFamily == AF_INET){
621     listEntry = (struct RouterListEntry *)malloc(sizeof(struct RouterListEntry));
622     if(ParseElectionPacket(rcvPkt, listEntry, skfd)){
623       OLSR_PRINTF(1,"processing ipv4 packet \n");
624       if(UpdateRouterList(listEntry))
625         free(listEntry);
626     }
627     else{
628       free(listEntry);
629       return;                                   //packet not valid
630     }
631   }
632   else{
633     listEntry6 = (struct RouterListEntry6 *)malloc(sizeof(struct RouterListEntry6));
634     if(ParseElectionPacket6(rcvPkt, listEntry6, skfd)){
635       OLSR_PRINTF(1,"processing ipv6 packet");
636       if(UpdateRouterList6(listEntry6))
637         free(listEntry6);
638     }
639     else{
640       free(listEntry6);
641       return;                                   //packet not valid
642     }
643   }
644   
645   }
646  return;
647 }