Merge branch 'master' into scheduler_cleanup
[olsrd.git] / lib / obamp / src / obamp.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42
43 /* System includes */
44 #include <stddef.h>             /* NULL */
45 #include <sys/types.h>          /* ssize_t */
46 #include <string.h>             /* strerror() */
47 #include <stdarg.h>             /* va_list, va_start, va_end */
48 #include <errno.h>              /* errno */
49 #include <assert.h>             /* assert() */
50 #include <linux/if_ether.h>     /* ETH_P_IP */
51 #include <linux/if_packet.h>    /* struct sockaddr_ll, PACKET_MULTICAST */
52 #include <signal.h>             /* sigset_t, sigfillset(), sigdelset(), SIGINT */
53 #include <netinet/ip.h>         /* struct ip */
54 #include <netinet/udp.h>        /* struct udphdr */
55 #include <unistd.h>             /* close() */
56 #include <stdlib.h>             /* free() */
57
58 #include <netinet/in.h>
59 #include <netinet/ip6.h>
60
61 #include <fcntl.h>              /* fcntl() */
62
63 /* OLSRD includes */
64 #include "plugin_util.h"        /* set_plugin_int */
65 #include "defs.h"               /* olsr_cnf, //OLSR_PRINTF */
66 #include "ipcalc.h"
67 #include "olsr.h"               /* //OLSR_PRINTF */
68 #include "mid_set.h"            /* mid_lookup_main_addr() */
69 #include "link_set.h"           /* get_best_link_to_neighbor() */
70 #include "net_olsr.h"           /* ipequal */
71 #include "olsr_logging.h"
72
73 /* plugin includes */
74 #include "obamp.h"
75 #include "common/list.h"
76
77
78 #define OLSR_FOR_ALL_OBAMPNODE_ENTRIES(n, iterator) list_for_each_element_safe(&ListOfObampNodes, n, list, iterator)
79 #define OLSR_FOR_ALL_OBAMPSNIFF_ENTRIES(s, iterator) list_for_each_element_safe(&ListOfObampSniffingIf, s, list, iterator)
80
81 struct ObampNodeState *myState;        //Internal state of the OBAMP node
82
83 /*
84 List of all other OBAMP nodes
85 if there is a mesh link the isMesh flag is set to 1
86 if the link is used in the distribution tree the isTree flag is set to 1
87 */
88 struct list_entity ListOfObampNodes;
89
90 //List of Non OLSR Interfaces to capture and send multicast traffic to
91 struct list_entity ListOfObampSniffingIf;
92
93 //udp socket used for OBAMP signalling
94 int sdudp = -1;
95
96 /*
97 When Outer Tree Create is triggered, a OBAMP node uses this function to
98 determine the closer OBAMP node that has a TreeLink
99 */
100 static struct ObampNode *
101 select_tree_anchor(void)
102 {
103
104   struct ObampNode *tmp, *iterator;               //temp pointers used when parsing the list
105   struct ObampNode *best;
106   struct rt_entry *rt;                 //"rt->rt_best->rtp_metric.cost" is the value you are looking for, a 32 bit
107
108   unsigned int mincost = 15;
109
110   best = NULL;
111
112   if (list_is_empty(&ListOfObampNodes)) {     //if the list is empty
113     OLSR_DEBUG(LOG_PLUGINS, "List empty can't create Overlay Mesh");
114     return NULL;
115   }
116
117   //Scroll the list
118   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
119     if (tmp->status == 1) {
120       rt = olsr_lookup_routing_table(&tmp->neighbor_ip_addr);
121
122       if (rt == NULL) {       //route is not present yet
123         OLSR_DEBUG(LOG_PLUGINS, "No route present to this anchor");
124         continue;
125       }
126       //update best neighbor
127       if ((rt->rt_best->rtp_metric.cost / 65536) < mincost)
128         best = tmp;
129     }
130   }
131   return best;
132 }
133
134 //Creates a OBAMP_DATA message and sends it to the specified destination
135 static int
136 SendOBAMPData(struct in_addr *addr, unsigned char *ipPacket, int nBytes)
137 {
138
139   struct sockaddr_in si_other;
140   struct OBAMP_data_message4 data_msg;
141
142   memset(&data_msg, 0, sizeof(data_msg));
143   data_msg.MessageID = OBAMP_DATA;
144   data_msg.router_id = (u_int32_t) myState->myipaddr.v4.s_addr;
145   data_msg.last_hop = (u_int32_t) myState->myipaddr.v4.s_addr;
146
147   data_msg.CoreAddress = (u_int32_t) myState->CoreAddress.v4.s_addr;
148
149   data_msg.SequenceNumber = myState->DataSequenceNumber;
150   myState->DataSequenceNumber++;
151
152   if (nBytes >= 1471) {
153     OLSR_DEBUG(LOG_PLUGINS, "PACKET DROPPED: %d bytes are too much",nBytes);
154     return 1;
155   }
156
157   memcpy(data_msg.data, ipPacket, nBytes);
158
159   data_msg.datalen = nBytes;
160
161   memset((char *)&si_other, 0, sizeof(si_other));
162   si_other.sin_family = AF_INET;
163   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
164   si_other.sin_addr = *addr;
165   //sendto(sdudp, data_msg, sizeof(struct OBAMP_data_message), 0, (struct sockaddr *)&si_other, sizeof(si_other));
166   //TODO: this 17 magic number is okay only for IPv4, we do not worry about this now
167   sendto(sdudp, &data_msg, 17+data_msg.datalen, 0, (struct sockaddr *)&si_other, sizeof(si_other));
168   return 0;
169
170 }
171
172 static int
173 CreateCaptureSocket(const char *ifName)
174 {
175   int ifIndex = if_nametoindex(ifName);
176   struct packet_mreq mreq;
177   struct ifreq req;
178   struct sockaddr_ll bindTo;
179   int skfd = 0;
180
181   /* Open cooked IP packet socket */
182   if (olsr_cnf->ip_version == AF_INET) {
183     skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
184   } else {
185     skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
186   }
187   if (skfd < 0) {
188     OLSR_DEBUG(LOG_PLUGINS, "socket(PF_PACKET) error");
189     return -1;
190   }
191
192   /* Set interface to promiscuous mode */
193   memset(&mreq, 0, sizeof(struct packet_mreq));
194   mreq.mr_ifindex = ifIndex;
195   mreq.mr_type = PACKET_MR_PROMISC;
196   if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
197     OLSR_DEBUG(LOG_PLUGINS, "setsockopt(PACKET_MR_PROMISC) error");
198     close(skfd);
199     return -1;
200   }
201
202   /* Get hardware (MAC) address */
203   memset(&req, 0, sizeof(struct ifreq));
204   strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
205   req.ifr_name[IFNAMSIZ - 1] = '\0';    /* Ensures null termination */
206   if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0) {
207     OLSR_DEBUG(LOG_PLUGINS, "error retrieving MAC address");
208     close(skfd);
209     return -1;
210   }
211
212   /* Bind the socket to the specified interface */
213   memset(&bindTo, 0, sizeof(bindTo));
214   bindTo.sll_family = AF_PACKET;
215   if (olsr_cnf->ip_version == AF_INET) {
216     bindTo.sll_protocol = htons(ETH_P_IP);
217   } else {
218     bindTo.sll_protocol = htons(ETH_P_IPV6);
219   }
220   bindTo.sll_ifindex = ifIndex;
221   memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
222   bindTo.sll_halen = IFHWADDRLEN;
223
224   if (bind(skfd, (struct sockaddr *)&bindTo, sizeof(bindTo)) < 0) {
225     OLSR_DEBUG(LOG_PLUGINS, "bind() error");
226     close(skfd);
227     return -1;
228   }
229
230   /* Set socket to blocking operation */
231   if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
232     OLSR_DEBUG(LOG_PLUGINS, "fcntl() error");
233     close(skfd);
234     return -1;
235   }
236
237   if (NULL == olsr_socket_add(skfd, &EncapFlowInObamp, NULL, OLSR_SOCKET_READ)) {
238     OLSR_DEBUG(LOG_PLUGINS, "Could not register socket with scheduler");
239     close(skfd);
240     return -1;
241   }
242
243   return skfd;
244 }                               /* CreateCaptureSocket */
245
246
247 static int
248 CreateObampSniffingInterfaces(void)
249 {
250
251   struct ObampSniffingIf *tmp, *iterator;
252   OLSR_DEBUG(LOG_PLUGINS, "CreateObampSniffingInterfaces");
253
254   if (list_is_empty(&ListOfObampSniffingIf)) {        //if the list is empty
255     OLSR_DEBUG(LOG_PLUGINS, "List of sniffin interfaces was empty");
256     return 0;
257   }
258
259   OLSR_DEBUG(LOG_PLUGINS, "adding interfaces");
260
261   OLSR_FOR_ALL_OBAMPSNIFF_ENTRIES(tmp, iterator) {
262     tmp->skd = CreateCaptureSocket(tmp->ifName);
263   }
264   return 0;
265 }
266
267
268 static int
269 IsMulticast(union olsr_ip_addr *ipAddress)
270 {
271   assert(ipAddress != NULL);
272
273   return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
274 }
275
276
277
278 static void
279 activate_tree_link(struct OBAMP_tree_link_ack *ack)
280 {
281 #if !defined(REMOVE_LOG_DEBUG)
282   struct ipaddr_str buf;
283 #endif
284   struct ObampNode *tmp, *iterator;
285
286   if (memcmp(&myState->CoreAddress.v4, &ack->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
287     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
288     return;
289   }
290
291   if (ack->SequenceNumber != myState->tree_req_sn - 1) {
292
293     OLSR_DEBUG(LOG_PLUGINS, "ACK DISCARDED WRONG SEQ NUMBER");
294     return;
295   } else {
296
297     OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
298       if (tmp->neighbor_ip_addr.v4.s_addr == ack->router_id.v4.s_addr) {
299
300         tmp->isTree = 1;
301         myState->TreeHeartBeat = TREE_HEARTBEAT;
302         OLSR_DEBUG(LOG_PLUGINS, "Tree link to %s activated", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
303         return;
304
305       }
306     }
307   }
308
309 }
310
311
312
313 /*
314 When we select a other OBAMP node as a overlay neighbor, we start to send HELLOs to him
315 to inform we are using the unicast path from us to him  as a overlay mesh link
316 */
317 static void
318 obamp_hello(struct in_addr *addr)
319 {
320
321   struct OBAMP_hello hello;
322   struct sockaddr_in si_other;
323
324   memset(&hello, 0, sizeof(hello));
325   hello.MessageID = OBAMP_HELLO;
326   //TODO: refresh IP address
327   hello.router_id = myState->myipaddr;
328   hello.CoreAddress = myState->CoreAddress;
329
330   //TODO: implement sequence number
331   //hello->HelloSequenceNumber = myState->something;
332   //myState->something++;
333
334   memset((char *)&si_other, 0, sizeof(si_other));
335   si_other.sin_family = AF_INET;
336   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
337   si_other.sin_addr = *addr;
338   sendto(sdudp, &hello, sizeof(struct OBAMP_hello), 0, (struct sockaddr *)&si_other, sizeof(si_other));
339 }
340
341
342 //Destroy a Tree Link
343 static void
344 send_destroy_tree_link(struct in_addr *addr)
345 {
346   struct OBAMP_tree_destroy msg;
347   struct sockaddr_in si_other;
348   #if !defined(REMOVE_LOG_DEBUG)
349   struct ipaddr_str buf;
350   #endif
351  
352
353   OLSR_DEBUG(LOG_PLUGINS, "Sending tree destroy to: %s", ip4_to_string(&buf, *addr));
354  
355   memset(&msg, 0, sizeof(msg));
356   msg.MessageID = OBAMP_TREE_DESTROY;
357   //TODO: refresh IP address
358   msg.router_id = myState->myipaddr;
359   msg.CoreAddress = myState->CoreAddress;
360
361   memset((char *)&si_other, 0, sizeof(si_other));
362   si_other.sin_family = AF_INET;
363   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
364   si_other.sin_addr = *addr;
365   sendto(sdudp, &msg, sizeof(struct OBAMP_tree_destroy), 0, (struct sockaddr *)&si_other, sizeof(si_other));
366 }
367
368
369 //Request a Tree Link
370 static void
371 tree_link_req(struct in_addr *addr)
372 {
373   if (myState->TreeRequestDelay == 0) { 
374   struct OBAMP_tree_link_req req;
375   struct sockaddr_in si_other;
376   #if !defined(REMOVE_LOG_DEBUG)
377   struct ipaddr_str buf;
378   #endif
379  
380
381   OLSR_DEBUG(LOG_PLUGINS, "Sending tree request to: %s", ip4_to_string(&buf, *addr));
382  
383   memset(&req, 0, sizeof(req));
384   req.MessageID = OBAMP_TREE_REQ;
385   //TODO: refresh IP address
386   req.router_id = myState->myipaddr;
387   req.CoreAddress = myState->CoreAddress;
388
389   req.SequenceNumber = myState->tree_req_sn;
390   myState->tree_req_sn++;
391
392   memset((char *)&si_other, 0, sizeof(si_other));
393   si_other.sin_family = AF_INET;
394   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
395   si_other.sin_addr = *addr;
396   myState->TreeRequestDelay=_TREE_REQUEST_DELAY_;
397   sendto(sdudp, &req, sizeof(struct OBAMP_tree_link_req), 0, (struct sockaddr *)&si_other, sizeof(si_other));
398 }
399 else OLSR_DEBUG(LOG_PLUGINS,"Do not send Tree Link Request because there is another one running");
400 }
401
402 static void
403 tree_link_ack(struct OBAMP_tree_link_req *req)
404 {
405
406   struct sockaddr_in si_other;
407   struct in_addr addr;
408
409   struct ObampNode *tmp, *iterator;
410
411 #if !defined(REMOVE_LOG_DEBUG)
412   struct ipaddr_str buf;
413 #endif
414
415   struct OBAMP_tree_link_ack ack;
416
417   //Check Core Address
418   if (memcmp(&myState->CoreAddress.v4, &req->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
419     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
420     return;
421   }
422   //TODO: other checks ?
423
424
425   memset(&ack, 0, sizeof(ack));
426   ack.MessageID = OBAMP_TREE_ACK;
427   //TODO: refresh IP address
428   ack.router_id = myState->myipaddr;
429   ack.CoreAddress = myState->CoreAddress;
430
431   ack.SequenceNumber = req->SequenceNumber;
432
433   addr = req->router_id.v4;
434
435   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
436     if (tmp->neighbor_ip_addr.v4.s_addr == req->router_id.v4.s_addr) {
437
438       tmp->isTree = 1;
439       OLSR_DEBUG(LOG_PLUGINS, "Tree link to %s activated", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
440       break;
441     }
442   }
443
444   memset((char *)&si_other, 0, sizeof(si_other));
445   si_other.sin_family = AF_INET;
446   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
447   si_other.sin_addr = addr;
448   sendto(sdudp, &ack, sizeof(struct OBAMP_tree_link_req), 0, (struct sockaddr *)&si_other, sizeof(si_other));
449 }
450
451
452 static void
453 init_overlay_neighbor(struct ObampNode *n)
454 {
455
456   n->Texpire = _Texpire_;       //If this value expires the OBAMP node is removed from the list
457   n->isMesh = 0;
458   n->wasMesh = 0;
459   n->MeshLock = 0;
460   n->isTree = 0;
461   n->outerTreeLink = 0;
462   n->DataSeqNumber = 0;
463 }
464
465 static void
466 tree_create_forward_to(struct in_addr *addr, struct OBAMP_tree_create *mytc)
467 {
468
469   struct sockaddr_in si_other;
470   struct OBAMP_tree_create temptc;
471
472   memset(&temptc, 0, sizeof(temptc));
473   memcpy(&temptc, mytc, sizeof(struct OBAMP_tree_create));
474
475   //Check Core Address
476   if (memcmp(&myState->CoreAddress.v4, &temptc.CoreAddress.v4, sizeof(struct in_addr)) != 0) {
477     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
478     return;
479   }
480   //Update router id
481   temptc.router_id = myState->myipaddr;
482
483   memset((char *)&si_other, 0, sizeof(si_other));
484   si_other.sin_family = AF_INET;
485   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
486   si_other.sin_addr = *addr;
487
488   sendto(sdudp, &temptc, sizeof(struct OBAMP_tree_create), 0, (struct sockaddr *)&si_other, sizeof(si_other));
489 }
490
491 static void
492 tree_create_gen(struct in_addr *addr)
493 {
494   struct OBAMP_tree_create mytc;
495   struct sockaddr_in si_other;
496
497   OLSR_DEBUG(LOG_PLUGINS, "Calling tree_create_gen\n");
498
499   memset(&mytc, 0, sizeof(mytc));
500   mytc.MessageID = OBAMP_TREECREATE;
501   mytc.router_id = myState->myipaddr;
502   mytc.CoreAddress = myState->CoreAddress;
503   myState->TreeCreateSequenceNumber++;
504   mytc.SequenceNumber = myState->TreeCreateSequenceNumber;
505
506   memset((char *)&si_other, 0, sizeof(si_other));
507   si_other.sin_family = AF_INET;
508   si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
509   si_other.sin_addr = *addr;
510   sendto(sdudp, &mytc, sizeof(struct OBAMP_tree_create), 0, (struct sockaddr *)&si_other, sizeof(si_other));
511 }
512
513
514 static void
515 printObampNodesList(void)
516 {
517
518   int i = 1;
519 #if !defined(REMOVE_LOG_DEBUG)
520   struct ipaddr_str buf;
521 #endif
522   struct ObampNode *tmp, *iterator;
523
524   if (list_is_empty(&ListOfObampNodes)) {     //if the list is empty
525     return;
526   }
527
528
529   OLSR_DEBUG(LOG_PLUGINS, "--------------------NODE STATUS---------");
530   OLSR_DEBUG(LOG_PLUGINS, "---Current Core: %s", ip4_to_string(&buf, myState->CoreAddress.v4));
531   OLSR_DEBUG(LOG_PLUGINS, "---Current Parent: %s", ip4_to_string(&buf, myState->ParentId.v4));
532
533
534   OLSR_DEBUG(LOG_PLUGINS, "Number \t IP \t\t IsMesh \t IsTree \t MeshLock \t outerTreeLink");
535
536   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
537     OLSR_DEBUG(LOG_PLUGINS, "%d \t\t %s \t %d \t\t %d \t\t %d \t\t %d", i, ip4_to_string(&buf, tmp->neighbor_ip_addr.v4),
538                tmp->isMesh, tmp->isTree, tmp->MeshLock, tmp->outerTreeLink);
539
540     i++;
541   }
542   OLSR_DEBUG(LOG_PLUGINS, "----------------------------------------");
543 }
544
545 static int
546 DoIHaveATreeLink(void)
547 {
548
549   //struct ipaddr_str buf;
550   struct ObampNode *tmp, *iterator;
551
552   if (list_is_empty(&ListOfObampNodes)) {     //if the list is empty
553     return 0;
554   }
555
556   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
557     if (tmp->isTree == 1) {
558       return 1;
559     }
560   }
561   return 0;
562 }
563
564
565 void
566 unsolicited_tree_destroy(void *x)
567 {
568
569   //struct ipaddr_str buf;
570   struct ObampNode *tmp, *iterator;
571
572   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
573     if (tmp->isTree == 0) {
574       send_destroy_tree_link(&tmp->neighbor_ip_addr.v4);
575     }
576   }
577   x = NULL;
578 }
579
580 static int
581 DoIHaveAMeshLink(void)
582 {
583
584   //struct ipaddr_str buf;
585   struct ObampNode *tmp, *iterator;
586
587   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
588     if (tmp->isMesh == 1) {
589       return 1;
590     }
591   }
592   return 0;
593 }
594
595 static void
596 reset_tree_links(void)
597 {
598   struct ObampNode *tmp, *iterator;
599
600   OLSR_DEBUG(LOG_PLUGINS,"Reset Tree Links Now");
601
602   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
603     tmp->isTree = 0;
604     tmp->outerTreeLink = 0;
605   }
606
607   memset(&myState->ParentId.v4, 0, sizeof(myState->ParentId.v4));
608   memset(&myState->OldParentId.v4, 1, sizeof(myState->OldParentId.v4));
609   myState->TreeCreateSequenceNumber=0;
610 };
611
612
613 //I received a request to deactivate a tree link
614 static void
615 deactivate_tree_link(struct OBAMP_tree_destroy *destroy_msg)
616 {
617 #if !defined(REMOVE_LOG_DEBUG)
618   struct ipaddr_str buf;
619 #endif
620   struct ObampNode *tmp, *iterator;
621
622   if (memcmp(&myState->CoreAddress.v4, &destroy_msg->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
623     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
624     return;
625   }
626
627   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
628     if (tmp->neighbor_ip_addr.v4.s_addr == destroy_msg->router_id.v4.s_addr) {
629       tmp->isTree = 0;
630       OLSR_DEBUG(LOG_PLUGINS, "Tree link to %s deactivated", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
631         
632       if (memcmp(&tmp->neighbor_ip_addr.v4, &myState->ParentId.v4, sizeof(struct in_addr)) == 0) {
633         OLSR_DEBUG(LOG_PLUGINS,"RESET TREE LINKS: I lost tree link with my PARENT");
634         reset_tree_links();
635       }
636       return;
637     }
638   }
639 }
640
641 //Core Election. The Core is the one with the smallest IP Address
642 static void
643 CoreElection(void)
644 {
645 #if !defined(REMOVE_LOG_DEBUG)
646   struct ipaddr_str buf;
647 #endif
648   struct ObampNode *tmp, *iterator;
649   u_int32_t smallestIP = 0xFFFFFFFF;
650
651   //Update my current IP address
652   memcpy(&myState->myipaddr.v4, &olsr_cnf->router_id, olsr_cnf->ipsize);
653
654   OLSR_DEBUG(LOG_PLUGINS, "SETUP: my IP - %s", ip4_to_string(&buf, myState->myipaddr.v4));
655
656
657   if (list_is_empty(&ListOfObampNodes)) {     //if the list is empty
658     OLSR_DEBUG(LOG_PLUGINS, "CoreElection: I'm alone I'm the core");
659     myState->CoreAddress = myState->myipaddr;
660     myState->iamcore = 1;
661     myState->TreeCreateSequenceNumber = 0;
662     OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links");
663     reset_tree_links();
664     return;
665   }
666
667   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
668     if (tmp->neighbor_ip_addr.v4.s_addr < smallestIP) {
669       smallestIP = tmp->neighbor_ip_addr.v4.s_addr;
670       OLSR_DEBUG(LOG_PLUGINS, "CoreElection: current smallest IP is - %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
671     };
672   }
673
674   //Check if I'm the core.
675   if (myState->myipaddr.v4.s_addr < smallestIP) {     //I'm the core
676     if (myState->myipaddr.v4.s_addr == myState->CoreAddress.v4.s_addr) {      //I'm was already the core
677       return;
678     }
679
680     //I'm becoming core
681     myState->CoreAddress = myState->myipaddr;
682     myState->iamcore = 1;
683     myState->TreeCreateSequenceNumber = 0;
684     OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
685     reset_tree_links();
686     OLSR_DEBUG(LOG_PLUGINS, "I'm the core");
687   } else {
688     if (myState->CoreAddress.v4.s_addr == smallestIP) {       //the core did not change
689       return;
690     }
691
692     //core changed
693     myState->iamcore = 0;
694     myState->CoreAddress.v4.s_addr = smallestIP;
695     OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links");
696     reset_tree_links();
697     OLSR_DEBUG(LOG_PLUGINS, "CoreElection: current Core is - %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
698   }
699 }
700
701 //Starts a UDP listening port for OBAMP signalling
702 static int
703 UdpServer(void)
704 {
705   struct sockaddr_in addr;
706
707   if ((sdudp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
708     OLSR_DEBUG(LOG_PLUGINS, "Socket UDP error");
709     return -1;
710   }
711
712   memset((void *)&addr, 0, sizeof(addr));       /* clear server address */
713   addr.sin_family = AF_INET;    /* address type is INET */
714   addr.sin_port = htons(OBAMP_SIGNALLING_PORT);
715   addr.sin_addr.s_addr = htonl(INADDR_ANY);     /* connect from anywhere */
716   /* bind socket */
717   if (bind(sdudp, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
718     OLSR_DEBUG(LOG_PLUGINS, "Socket UDP BIND error");
719     return (-1);
720   }
721
722   olsr_socket_add(sdudp, &ObampSignalling, NULL, OLSR_SOCKET_READ);
723
724   return 0;
725
726 }
727
728 static void
729 decap_data(char *buffer)
730 {
731   struct ObampSniffingIf *tmp, *iterator;
732   unsigned char *ipPacket;
733   int stripped_len;
734   struct ip *ipHeader;
735   struct ip6_hdr *ip6Header;
736   struct OBAMP_data_message4 *msg;
737   int nBytesWritten;
738   struct sockaddr_ll dest;
739   msg = (struct OBAMP_data_message4 *)buffer;
740
741   ipPacket = msg->data;
742
743   ipHeader = (struct ip *)ipPacket;
744   ip6Header = (struct ip6_hdr *)ipPacket;
745
746   OLSR_FOR_ALL_OBAMPSNIFF_ENTRIES(tmp, iterator) {
747     memset(&dest, 0, sizeof(dest));
748     dest.sll_family = AF_PACKET;
749     if ((ipPacket[0] & 0xf0) == 0x40) {
750       dest.sll_protocol = htons(ETH_P_IP);
751       stripped_len = ntohs(ipHeader->ip_len);
752     }
753     if ((ipPacket[0] & 0xf0) == 0x60) {
754       dest.sll_protocol = htons(ETH_P_IPV6);
755       stripped_len = 40 + ntohs(ip6Header->ip6_plen); //IPv6 Header size (40) + payload_len
756     }
757     //TODO: if packet is not IP die here
758
759     dest.sll_ifindex = if_nametoindex(tmp->ifName);
760     dest.sll_halen = IFHWADDRLEN;
761
762     /* Use all-ones as destination MAC address. When the IP destination is
763      * a multicast address, the destination MAC address should normally also
764      * be a multicast address. E.g., when the destination IP is 224.0.0.1,
765      * the destination MAC should be 01:00:5e:00:00:01. However, it does not
766      * seem to matter when the destination MAC address is set to all-ones
767      * in that case. */
768     memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
769
770     nBytesWritten = sendto(tmp->skd, ipPacket, stripped_len, 0, (struct sockaddr *)&dest, sizeof(dest));
771     if (nBytesWritten != stripped_len) {
772       OLSR_DEBUG(LOG_PLUGINS, "sendto() error forwarding unpacked encapsulated pkt on \"%s\"", tmp->ifName);
773     } else {
774       OLSR_DEBUG(LOG_PLUGINS, "OBAMP: --> unpacked and forwarded on \"%s\"\n", tmp->ifName);
775     }
776   }
777 }
778
779
780
781 static int
782 CheckDataFromTreeLink(char *buffer)
783 {
784
785   struct ObampNode *tmp, *iterator;
786   struct OBAMP_data_message4 *data_msg;
787
788   data_msg = (struct OBAMP_data_message4 *)buffer;
789
790   //Scroll the list
791   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
792     //Scroll the list until we find the entry relative to the last hop of the packet we are processing
793     if (memcmp(&tmp->neighbor_ip_addr.v4, &data_msg->last_hop, sizeof(struct in_addr)) == 0) {
794       if (tmp->isTree == 1) {  //OK we receive data from a neighbor that we have a tree link with
795         return 1;
796       }
797       OLSR_DEBUG(LOG_PLUGINS, "DISCARDING DATA PACKET SENT BY NOT TREE NEIGHBOR");
798       send_destroy_tree_link(&tmp->neighbor_ip_addr.v4);
799       return 0;
800     }
801   }
802   return 0;
803 }
804
805
806 static int
807 CheckDupData(char *buffer)
808 {
809
810   struct ObampNode *tmp, *iterator;
811   struct OBAMP_data_message4 *data_msg;
812
813   data_msg = (struct OBAMP_data_message4 *)buffer;
814
815   //Scroll the list
816   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
817     if (memcmp(&tmp->neighbor_ip_addr.v4, &data_msg->router_id, sizeof(struct in_addr)) == 0) {
818       OLSR_DEBUG(LOG_PLUGINS, "Processing Data Packet %d - Last seen was %d",data_msg->SequenceNumber, tmp->DataSeqNumber);
819
820       if (tmp->DataSeqNumber == 0) {  //First packet received from this host
821         tmp->DataSeqNumber = data_msg->SequenceNumber;
822         return 1;
823       }
824
825       if ( ((data_msg->SequenceNumber > tmp->DataSeqNumber) && ((data_msg->SequenceNumber - tmp->DataSeqNumber ) <= 127)) || ((tmp->DataSeqNumber > data_msg->SequenceNumber) && ((tmp->DataSeqNumber - data_msg->SequenceNumber) > 127 ))) //data_msg->SequenceNumber > tmp->DataSeqNumber
826       {
827         tmp->DataSeqNumber = data_msg->SequenceNumber;
828         return 1;
829       }
830       OLSR_DEBUG(LOG_PLUGINS, "DISCARDING DUP PACKET");
831       return 0;
832     }
833   }
834   return 1;
835 }
836
837 static void
838 forward_obamp_data(char *buffer)
839 {
840
841 #if !defined(REMOVE_LOG_DEBUG)
842   struct ipaddr_str buf;
843   struct ipaddr_str buf2;
844 #endif
845   struct ObampNode *tmp, *iterator;
846   struct OBAMP_data_message4 *data_msg;
847   struct sockaddr_in si_other;
848   struct in_addr temporary;
849
850
851   data_msg = (struct OBAMP_data_message4 *)buffer;
852   temporary.s_addr  = data_msg->last_hop;
853   data_msg->last_hop = myState->myipaddr.v4.s_addr;
854
855   //Scroll the list
856   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
857     if (tmp->isTree == 1 && memcmp(&tmp->neighbor_ip_addr.v4, &temporary.s_addr, 4) != 0) {
858       OLSR_DEBUG(LOG_PLUGINS, "FORWARDING OBAMP DATA TO node %s because come from %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4), ip4_to_string(&buf2,temporary));
859
860       //FORWARD DATA
861       memset((char *)&si_other, 0, sizeof(si_other));
862       si_other.sin_family = AF_INET;
863       si_other.sin_port = htons(OBAMP_SIGNALLING_PORT);
864       si_other.sin_addr = tmp->neighbor_ip_addr.v4;
865
866       //sendto(sdudp, data_msg, sizeof(struct OBAMP_data_message), 0, (struct sockaddr *)&si_other, sizeof(si_other));
867       sendto(sdudp, data_msg, 17+data_msg->datalen, 0, (struct sockaddr *)&si_other, sizeof(si_other));
868     }
869   }
870 }
871
872
873 static void
874 manage_hello(char *packet)
875 {
876
877   struct OBAMP_hello *hello;
878
879   struct ObampNode *tmp, *iterator;
880
881   hello = (struct OBAMP_hello *)packet;
882
883   //FIRST OF ALL CHECK CORE
884   if (memcmp(&myState->CoreAddress.v4, &hello->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
885     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
886     return;
887   }
888
889   if (!list_is_empty(&ListOfObampNodes)) {     //if the list is empty
890     OLSR_DEBUG(LOG_PLUGINS, "Very strange, list cannot be empty here !");
891     return;
892   }
893
894   //Scroll the list
895   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
896      if (memcmp(&tmp->neighbor_ip_addr.v4, &hello->router_id.v4, sizeof(struct in_addr)) == 0) {       //I search in the list the neighbor I received the hello from
897       tmp->isMesh = 1;
898       tmp->MeshLock = _MESH_LOCK_;
899     }
900   }
901 }
902
903 static void
904 manage_tree_create(char *packet)
905 {
906
907   struct OBAMP_tree_create *msg;
908
909 #if !defined(REMOVE_LOG_DEBUG)
910   struct ipaddr_str buf;
911   struct ipaddr_str buf2;              //buf to print debug infos
912 #endif
913
914   struct ObampNode *tmp, *iterator;
915
916   OLSR_DEBUG(LOG_PLUGINS,"manage_tree_create");
917   msg = (struct OBAMP_tree_create *)packet;
918
919   if (msg->MessageID != OBAMP_TREECREATE) {
920     OLSR_DEBUG(LOG_PLUGINS, "BIG PROBLEM, I'M IN THIS FUNCTION BUT MESSAGE IS NOT TREE CREATE");
921     return;
922   }
923
924   //FIRST OF ALL CHECK CORE
925   if (memcmp(&myState->CoreAddress.v4, &msg->CoreAddress.v4, sizeof(struct in_addr)) != 0) {
926     OLSR_DEBUG(LOG_PLUGINS, "Discarding message with no coherent core address");
927     return;
928   }
929   if (myState->iamcore == 1) {        //I'm core and receiving tree create over a loop
930     return;
931   }
932
933   // TODO: cleanup this statement
934   if ( (((msg->SequenceNumber > myState->TreeCreateSequenceNumber) && ((msg->SequenceNumber - myState->TreeCreateSequenceNumber ) <= 127))
935       || ((myState->TreeCreateSequenceNumber > msg->SequenceNumber) && ((myState->TreeCreateSequenceNumber - msg->SequenceNumber) > 127 ))
936        /*myState->TreeCreateSequenceNumber < msg->SequenceNumber*/) || myState->TreeCreateSequenceNumber == 0 ) {
937     //If tree create is not a duplicate
938     OLSR_DEBUG(LOG_PLUGINS, "myState->TreeCreateSequenceNumber < msg->SequenceNumber --- %d < %d",myState->TreeCreateSequenceNumber,msg->SequenceNumber);
939     myState->TreeCreateSequenceNumber = msg->SequenceNumber;
940
941     // A bug was fixed here a battlemeshv3
942     // myState->OldParentId.v4 = myState->ParentId.v4;
943     // myState->ParentId.v4 = msg->router_id.v4;
944
945     // if (memcmp(&myState->OldParentId.v4, &myState->ParentId.v4, sizeof(struct in_addr)) != 0)       //If it changed
946     if (memcmp(&msg->router_id.v4, &myState->ParentId.v4, sizeof(struct in_addr)) != 0)       //If it changed
947     {
948       OLSR_DEBUG(LOG_PLUGINS, "Receiving a tree message from a link that is not parent");
949       if (DoIHaveATreeLink() == 0 ) {
950         OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links");
951         reset_tree_links();
952         myState->ParentId.v4 = msg->router_id.v4;
953         myState->OldParentId.v4 = myState->ParentId.v4;
954         tree_link_req(&msg->router_id.v4);
955       }
956       else {
957         // I have a tree link already, evaluate new parent ??
958       }
959     }
960     else { //Receiving a TreeCreate from my parent so I can refresh hearthbeat
961       myState->TreeHeartBeat = TREE_HEARTBEAT;
962         
963       // FORWARD the tree message on the mesh
964       if (list_is_empty(&ListOfObampNodes)) {       //if the list is empty
965         OLSR_DEBUG(LOG_PLUGINS, "Very strange, list cannot be empty here !");
966       }
967
968       //Scroll the list
969       OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
970         if (tmp->isMesh == 1 && memcmp(&tmp->neighbor_ip_addr.v4, &msg->router_id.v4, sizeof(struct in_addr)) != 0) {
971           //Is neighbor and not the originator of this tree create
972           if (DoIHaveATreeLink() == 1 ) { //I forward only if I have a link tree to the core ready
973             tree_create_forward_to(&tmp->neighbor_ip_addr.v4, msg);
974             OLSR_DEBUG(LOG_PLUGINS, "FORWARDING TREE CREATE ORIGINATOR %s TO node %s ", ip4_to_string(&buf2, msg->router_id.v4),
975                        ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
976           }
977         }
978       }
979     } //END IF TREE CREATE IS NOT A DUPLICATE
980   }
981   else {
982    OLSR_DEBUG(LOG_PLUGINS, "myState->TreeCreateSequenceNumber < msg->SequenceNumber --- %d < %d",myState->TreeCreateSequenceNumber,msg->SequenceNumber);
983    OLSR_DEBUG(LOG_PLUGINS, "DISCARDING DUP TREE CREATE");
984   }
985 }
986
987 void
988 ObampSignalling(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
989 {
990
991   char buffer[1500];
992   char text_buffer[300];
993   struct sockaddr_in addr;
994   int n = 0;
995   socklen_t len;
996   u_int8_t MessageID;
997
998   memset(&addr, 0, sizeof(struct sockaddr_in));
999   len = sizeof(addr);
1000
1001   if (skfd > 0) {
1002
1003     //OLSR_DEBUG(LOG_PLUGINS,"INCOMING OBAMP SIGNALLING");
1004
1005     n = recvfrom(skfd, buffer, 1500, 0, (struct sockaddr *)&addr, &len);
1006
1007     if (n < 0) {
1008       OLSR_DEBUG(LOG_PLUGINS, "recvfrom error");
1009     }
1010
1011     inet_ntop(AF_INET, &addr.sin_addr, text_buffer, sizeof(text_buffer));
1012     //OLSR_DEBUG(LOG_PLUGINS,"Request from host %s, port %d\n", text_buffer, ntohs(addr->sin_port));
1013
1014     MessageID = buffer[0];
1015
1016     switch (MessageID) {
1017
1018     case OBAMP_DATA:
1019       OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_DATA from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
1020
1021       if (CheckDupData(buffer) && CheckDataFromTreeLink(buffer) ) {
1022         forward_obamp_data(buffer);
1023         decap_data(buffer);
1024       }
1025
1026       break;
1027
1028     case OBAMP_HELLO:
1029       OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_HELLO from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
1030       manage_hello(buffer);
1031       break;
1032
1033     case OBAMP_TREECREATE:
1034       //do here
1035       OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREECREATE from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
1036       manage_tree_create(buffer);
1037
1038       break;
1039
1040     case OBAMP_TREE_REQ:
1041       OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_REQ from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
1042       tree_link_ack((struct OBAMP_tree_link_req *)buffer);
1043       break;
1044
1045     case OBAMP_TREE_ACK:
1046       //do here
1047       OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_ACK from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
1048       activate_tree_link((struct OBAMP_tree_link_ack *)buffer);
1049       break;
1050
1051
1052     case OBAMP_TREE_DESTROY:
1053       //do here
1054       OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_TREE_DESTROY from host %s, port %d\n", text_buffer, ntohs(addr.sin_port));
1055       deactivate_tree_link((struct OBAMP_tree_destroy *)buffer);
1056       break;
1057     }
1058
1059
1060   }                             //if skfd<0
1061
1062 }
1063
1064
1065 /*
1066 adds a IPv4 ObampNode in the list if it is new
1067 If a new node is added CoreElection is called to update the current core
1068 */
1069 int
1070 addObampNode4(struct in_addr *ipv4, u_int8_t status)
1071 {
1072 #if !defined(REMOVE_LOG_DEBUG)
1073   struct ipaddr_str buf;
1074 #endif
1075   struct ObampNode *neighbor_to_add;
1076   struct ObampNode *tmp, *iterator;
1077   neighbor_to_add = olsr_malloc(sizeof(struct ObampNode), "OBAMPNode");
1078
1079 //OLSR_DEBUG(LOG_PLUGINS,"Adding to list node - %s\n",ip4_to_string(&buf,*ipv4));
1080
1081
1082   if (list_is_empty(&ListOfObampNodes)) {     //Empty list
1083     //OLSR_DEBUG(LOG_PLUGINS,"List is empty %d adding first node\n",listold_empty(&ListOfObampNodes));
1084
1085     memcpy(&neighbor_to_add->neighbor_ip_addr.v4, ipv4, sizeof(neighbor_to_add->neighbor_ip_addr.v4));
1086     list_add_head(&ListOfObampNodes, &(neighbor_to_add->list));
1087
1088     init_overlay_neighbor(neighbor_to_add);
1089     neighbor_to_add->status = status;
1090
1091     OLSR_DEBUG(LOG_PLUGINS, "Added to list node as first node- %s\n", ip4_to_string(&buf, *ipv4));
1092
1093     CoreElection();
1094     return 0;
1095   }
1096
1097   //Some node already in list
1098
1099   //Scroll the list to check if the element already exists
1100   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1101     if (memcmp(&tmp->neighbor_ip_addr.v4, ipv4, sizeof(tmp->neighbor_ip_addr.v4)) == 0) {
1102       //OLSR_DEBUG(LOG_PLUGINS,"Node already present in list %s\n",ip4_to_string(&buf,*ipv4));
1103       tmp->Texpire = _Texpire_;       //Refresh Texpire
1104       neighbor_to_add->status = status;
1105       free(neighbor_to_add);
1106       return 1;
1107     }
1108   }
1109
1110   //Add element to list
1111   // neighbor_to_add->Texpire=_Texpire_; //Refresh Texpire
1112   OLSR_DEBUG(LOG_PLUGINS, "Adding to list node (NOT FIRST)- %s\n", ip4_to_string(&buf, *ipv4));
1113   memcpy(&neighbor_to_add->neighbor_ip_addr.v4, ipv4, sizeof(neighbor_to_add->neighbor_ip_addr.v4));
1114   list_add_tail(&ListOfObampNodes, &(neighbor_to_add->list));
1115   init_overlay_neighbor(neighbor_to_add);
1116   neighbor_to_add->status = status;
1117   CoreElection();
1118   return 0;
1119 }                               //End AddObampNode
1120
1121
1122
1123 /* -------------------------------------------------------------------------
1124  * Function   : PacketReceivedFromOLSR
1125  * Description: Handle a received packet from a OLSR message
1126  * Input      : Obamp Message
1127  * Output     : none
1128  * Return     : none
1129  * ------------------------------------------------------------------------- */
1130 static void
1131 PacketReceivedFromOLSR(union olsr_ip_addr *originator, const uint8_t *obamp_message, int len)
1132 {
1133   u_int8_t MessageID = obamp_message[0];
1134   const struct OBAMP_alive *alive;
1135 #if !defined(REMOVE_LOG_DEBUG)
1136   struct ipaddr_str buf;
1137 #endif
1138
1139   struct in_addr *myOriginator = (struct in_addr *)originator;
1140
1141 //TODO: this is useless now
1142   len = 0;
1143
1144 //See obamp.h
1145   switch (MessageID) {
1146
1147   case OBAMP_ALIVE:
1148     OLSR_DEBUG(LOG_PLUGINS, "OBAMP Received OBAMP_ALIVE from %s\n", ip4_to_string(&buf, *myOriginator));
1149     alive = (const struct OBAMP_alive *)obamp_message;
1150     addObampNode4(myOriginator, alive->status);
1151     printObampNodesList();
1152
1153     break;
1154   }
1155
1156
1157 }                               /* PacketReceivedFromOLSR */
1158
1159
1160 //OLSR parser, received OBAMP messages
1161 void
1162 olsr_parser(struct olsr_message *msg, struct interface *in_if
1163             __attribute__ ((unused)), union olsr_ip_addr *ipaddr, enum duplicate_status status __attribute__ ((unused)))
1164 {
1165   //OLSR_DEBUG(LOG_PLUGINS, "OBAMP PLUGIN: Received msg in parser\n");
1166
1167   if (msg->type != MESSAGE_TYPE) {
1168     return;
1169   }
1170
1171   /* Check if message originated from this node.
1172    *         If so - back off */
1173   if (olsr_ipcmp(&msg->originator, &olsr_cnf->router_id) == 0)
1174     return;
1175
1176   /* Check that the neighbor this message was received from is symmetric.
1177    *         If not - back off*/
1178   if (check_neighbor_link(ipaddr) != SYM_LINK) {
1179     //struct ipaddr_str strbuf;
1180     return;
1181   }
1182
1183   PacketReceivedFromOLSR(&msg->originator, msg->payload, msg->end - msg->payload);
1184 }
1185
1186 //Sends a packet in the OLSR network
1187 void
1188 olsr_obamp_gen(void *packet, int len)
1189 {
1190   /* send buffer: huge */
1191   uint8_t buffer[10240];
1192   struct olsr_message msg;
1193   struct interface *ifn, *iterator;
1194   uint8_t *curr, *sizeptr;
1195
1196   /* fill message */
1197   msg.type = MESSAGE_TYPE;
1198   msg.vtime = OBAMP_VALID_TIME * MSEC_PER_SEC;
1199   msg.originator = olsr_cnf->router_id;
1200   msg.ttl = MAX_TTL;
1201   msg.hopcnt = 0;
1202   msg.seqno = get_msg_seqno();
1203   msg.size = 0; /* put in later */
1204
1205   curr = buffer;
1206   sizeptr = olsr_put_msg_hdr(&curr, &msg);
1207   memcpy(curr, packet, len);
1208
1209   len = curr - buffer + len;
1210   pkt_put_u16(&sizeptr, len);
1211
1212   /* looping trough interfaces */
1213   OLSR_FOR_ALL_INTERFACES(ifn, iterator) {
1214     if (net_outbuffer_push(ifn, buffer, len) != len) {
1215       /* send data and try again */
1216       net_output(ifn);
1217       if (net_outbuffer_push(ifn, buffer, len) != len) {
1218         OLSR_DEBUG(LOG_PLUGINS, "OBAMP PLUGIN: could not send on interface: %s\n", ifn->int_name);
1219       }
1220     }
1221   }
1222 }
1223
1224 void
1225 outer_tree_create(void *x __attribute__ ((unused)))
1226 {
1227   struct ObampNode *tmp, *iterator;
1228
1229   if (!((DoIHaveATreeLink() == 0) && (myState->iamcore == 0))) {   //If there are tree links
1230     return;
1231   }
1232
1233   if (list_is_empty(&ListOfObampNodes) == 0) {   //if the list is empty
1234     OLSR_DEBUG(LOG_PLUGINS, "List empty can't send OUTER_TREE_CREATE");
1235   }
1236
1237   if (DoIHaveAMeshLink() == 0) {
1238     OLSR_DEBUG(LOG_PLUGINS, "Weird, no mesh links. Maybe other OBAMP nodes are very far (HUGE ETX)");
1239     return;
1240   }
1241
1242   // Update my current IP address
1243   memcpy(&myState->myipaddr.v4, &olsr_cnf->router_id, olsr_cnf->ipsize);
1244   //OLSR_DEBUG(LOG_PLUGINS,"SETUP: my IP - %s",ip4_to_string(&buf,myState->myipaddr.v4));
1245
1246   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1247     if ((tmp->neighbor_ip_addr.v4.s_addr < myState->myipaddr.v4.s_addr) && (tmp->isMesh == 1)) {
1248       return;             //I have a neighbor that will send a outer tree create for me
1249     }
1250   }
1251
1252   //tree create
1253   OLSR_DEBUG(LOG_PLUGINS, "OUTER TREE CREATE");
1254   tmp = select_tree_anchor();
1255   if (tmp == NULL) {
1256     OLSR_DEBUG(LOG_PLUGINS, "CANT FIND ANCHOR");
1257     return;
1258   }
1259
1260   tmp->isMesh = 1;
1261   tmp->outerTreeLink = 1;
1262   myState->OldParentId.v4 = tmp->neighbor_ip_addr.v4;
1263   myState->ParentId.v4 = tmp->neighbor_ip_addr.v4;
1264   myState->TreeHeartBeat = TREE_HEARTBEAT;
1265   tree_link_req(&tmp->neighbor_ip_addr.v4);
1266 }
1267
1268
1269 void
1270 tree_create(void *x __attribute__ ((unused)))
1271 {
1272 #if !defined(REMOVE_LOG_DEBUG)
1273   struct ipaddr_str buf;
1274 #endif
1275   struct ObampNode *tmp, *iterator;
1276
1277   // Check if I'm core
1278   if (myState->iamcore != 1) {
1279     return;
1280   }
1281
1282   if (list_is_empty(&ListOfObampNodes)) {   //if the list is empty
1283     OLSR_DEBUG(LOG_PLUGINS, "List empty can't send TREE_CREATE");
1284     return;
1285   }
1286
1287   //Scroll the list
1288   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1289     if (tmp->isMesh == 1) { //Is neighbor
1290       //send tree create
1291       tree_create_gen(&tmp->neighbor_ip_addr.v4);
1292
1293       OLSR_DEBUG(LOG_PLUGINS, "CORE SENDS TREE CREATE TO node %s ", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
1294     }
1295   }
1296 }
1297
1298
1299
1300
1301 void
1302 mesh_create(void *x __attribute__ ((unused)))
1303 {
1304 #if !defined(REMOVE_LOG_DEBUG)
1305   struct ipaddr_str buf;
1306 #endif
1307   struct ObampNode *tmp, *iterator;
1308
1309   struct rt_entry *rt;                 //"rt->rt_best->rtp_metric.cost" is the value you are looking for, a 32 bit
1310
1311   unsigned int mincost = 5;
1312
1313   int meshchanged = 0;
1314
1315   if (list_is_empty(&ListOfObampNodes)) {     //if the list is empty
1316     OLSR_DEBUG(LOG_PLUGINS, "List empty can't create Overlay Mesh");
1317     return;
1318   }
1319
1320   //Scroll the list
1321   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1322     //set every OBAMP node to be NOT neighbor
1323     tmp->wasMesh = tmp->isMesh;
1324
1325     //MeshLock in case mesh link is requested from neighbor
1326     if (tmp->MeshLock == 0 && tmp->outerTreeLink == 0) {
1327       tmp->isMesh = 0;
1328     }
1329
1330     rt = olsr_lookup_routing_table(&tmp->neighbor_ip_addr);
1331     if (rt == NULL) {         //route is not present yet
1332       continue;
1333     }
1334
1335     //OLSR_DEBUG(LOG_PLUGINS,"ROUTING TO node %s costs %u",ip4_to_string(&buf,tmp->neighbor_ip_addr.v4),rt->rt_best->rtp_metric.cost/65536);
1336
1337     if (rt->rt_best->rtp_metric.cost / 65536 > 5) {
1338       continue;               //we not not consider links that are poorer than ETX=5
1339     }
1340
1341     //update min cost
1342     if ((rt->rt_best->rtp_metric.cost / 65536) < mincost) {
1343       mincost = (rt->rt_best->rtp_metric.cost / 65536);
1344     }
1345   } //end for each
1346
1347   //now that I know the mincost to the closer OBAMP node I choose my neighbor set
1348   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1349     rt = olsr_lookup_routing_table(&tmp->neighbor_ip_addr);
1350     if (rt == NULL) {         //route is not present yet
1351       continue;
1352     }
1353
1354     if (rt->rt_best->rtp_metric.cost / 65536 > 5) {
1355       continue;               //we not not consider links that are poorer than ETX=5
1356     }
1357
1358     if ((rt->rt_best->rtp_metric.cost / 65536) - 1 < mincost) {       //Choose for mesh
1359       tmp->isMesh = 1;
1360       OLSR_DEBUG(LOG_PLUGINS, "Choosed Overlay Neighbor node %s costs %u", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4),
1361                  rt->rt_best->rtp_metric.cost / 65536);
1362
1363       obamp_hello(&tmp->neighbor_ip_addr.v4);
1364     }
1365
1366     if (tmp->outerTreeLink == 1) {
1367       obamp_hello(&tmp->neighbor_ip_addr.v4);
1368     }
1369
1370     if (tmp->isMesh != tmp->wasMesh) {
1371       meshchanged++;
1372       if (tmp->isMesh == 0 && tmp->isTree == 1) {
1373         tmp->isTree = 0;
1374         send_destroy_tree_link(&tmp->neighbor_ip_addr.v4);
1375
1376         if (memcmp(&tmp->neighbor_ip_addr.v4, &myState->ParentId.v4, sizeof(struct in_addr)) == 0) {
1377           OLSR_DEBUG(LOG_PLUGINS,"RESET TREE LINKS: I lost tree link with my PARENT");
1378           reset_tree_links();
1379         }
1380       }
1381     }
1382   }                           //end for each
1383
1384   if (meshchanged) {
1385     //trigger signalling
1386   }
1387 }
1388
1389
1390 void
1391 purge_nodes(void *x __attribute__ ((unused)))
1392 {
1393 #if !defined(REMOVE_LOG_DEBUG)
1394   struct ipaddr_str buf;
1395 #endif
1396   struct ObampNode *tmp, *iterator;
1397   int nodesdeleted = 0;
1398
1399   if (myState->TreeHeartBeat > 0) {
1400     myState->TreeHeartBeat--;
1401   }
1402
1403   if (myState->TreeRequestDelay > 0) {
1404     myState->TreeRequestDelay--;
1405   }
1406
1407   if (myState->TreeHeartBeat == 0 && myState->iamcore == 0){ 
1408     OLSR_DEBUG(LOG_PLUGINS,"Calling Reset Tree Links"); 
1409     reset_tree_links();
1410   }
1411
1412   //OLSR_DEBUG(LOG_PLUGINS,"OBAMP: Timer Expired Purging Nodes");
1413   if (list_is_empty(&ListOfObampNodes)) {     //if the list is empty
1414     //OLSR_DEBUG(LOG_PLUGINS,"OBAMP: List empty");
1415     return;
1416   }
1417
1418   OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1419     tmp->Texpire--;
1420     if (tmp->MeshLock != 0) {
1421       tmp->MeshLock--;
1422     }
1423
1424     //OLSR_DEBUG(LOG_PLUGINS,"Updating node %s with Texpire %d",ip4_to_string(&buf,tmp->neighbor_ip_addr.v4),tmp->Texpire);
1425     if (tmp->Texpire == 0) {  //purge
1426       OLSR_DEBUG(LOG_PLUGINS, "Purging node %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
1427       list_remove(&tmp->list);
1428       //OLSR_DEBUG(LOG_PLUGINS,"OBAMP CHECK EMPTY %d",listold_empty(&ListOfObampNodes));
1429
1430       free(tmp);
1431       nodesdeleted++;
1432     }
1433   }
1434
1435   if (nodesdeleted != 0) {
1436     CoreElection();
1437   }
1438 }
1439
1440
1441 void
1442 obamp_alive_gen(void *x __attribute__ ((unused)))
1443 {
1444   struct OBAMP_alive myAlive;
1445   OLSR_DEBUG(LOG_PLUGINS, "Calling obamp_alive_gen\n");
1446
1447   memset(&myAlive, 0, sizeof(myAlive));
1448   myAlive.MessageID = OBAMP_ALIVE;
1449   myAlive.status = DoIHaveATreeLink();
1450   olsr_obamp_gen(&myAlive, sizeof(struct OBAMP_alive));
1451 }
1452
1453
1454
1455 /*
1456 When a packet is captured on the sniffing interfaces, it is called EncapFlowInObamp
1457 here we check if the packet is multicast and we forward it to the overlay neighbors if we have a link tree
1458 */
1459
1460 void
1461 EncapFlowInObamp(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
1462 {
1463   unsigned char ipPacket[1500];        //TODO: optimize me
1464
1465 #if !defined(REMOVE_LOG_DEBUG)
1466   struct ipaddr_str buf;
1467 #endif
1468   struct ObampNode *tmp, *iterator;
1469
1470   union olsr_ip_addr dst;              /* Destination IP address in captured packet */
1471   struct ip *ipHeader;                 /* The IP header inside the captured IP packet */
1472   struct ip6_hdr *ipHeader6;           /* The IP header inside the captured IP packet */
1473
1474   struct sockaddr_ll pktAddr;
1475   socklen_t addrLen;
1476   int nBytes;
1477
1478   if (skfd < 0) {
1479     return;
1480   }
1481
1482   addrLen = sizeof(pktAddr);
1483
1484   nBytes = recvfrom(skfd, ipPacket, 1500,     //TODO: optimize me
1485                     0, (struct sockaddr *)&pktAddr, &addrLen);
1486   if (nBytes < 0) {
1487     return;
1488   }
1489
1490   /* Check if the number of received bytes is large enough for an IP
1491    * packet which contains at least a minimum-size IP header.
1492    * Note: There is an apparent bug in the packet socket implementation in
1493    * combination with VLAN interfaces. On a VLAN interface, the value returned
1494    * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
1495    * returned on a non-VLAN interface, for the same ethernet frame. */
1496   if (nBytes < (int)sizeof(struct ip)) {
1497     OLSR_DEBUG(LOG_PLUGINS, "Captured frame too short");
1498     return;                   /* for */
1499   }
1500
1501   if (pktAddr.sll_pkttype == PACKET_OUTGOING || pktAddr.sll_pkttype == PACKET_MULTICAST)      // ||
1502     //pktAddr.sll_pkttype == PACKET_BROADCAST)
1503   {
1504     //do here
1505     if ((ipPacket[0] & 0xf0) == 0x40) {       //IPV4
1506       ipHeader = (struct ip *)ipPacket;
1507
1508       dst.v4 = ipHeader->ip_dst;
1509
1510       /* Only forward multicast packets. If configured, also forward local broadcast packets */
1511       if (!IsMulticast(&dst)) {
1512         return;
1513       }
1514
1515       if (ipHeader->ip_p != SOL_UDP) {
1516         /* Not UDP */
1517         OLSR_DEBUG(LOG_PLUGINS, "NON UDP PACKET\n");
1518         return;               /* for */
1519       }
1520
1521       //Forward the packet to tree links
1522       OLSR_FOR_ALL_OBAMPNODE_ENTRIES(tmp, iterator) {
1523         if (tmp->isTree == 1) {
1524           OLSR_DEBUG(LOG_PLUGINS, "Pushing data to Tree link to %s", ip4_to_string(&buf, tmp->neighbor_ip_addr.v4));
1525           SendOBAMPData(&tmp->neighbor_ip_addr.v4, ipPacket, nBytes);
1526         }
1527       }
1528     }                         //END IPV4
1529     else if ((ipPacket[0] & 0xf0) == 0x60) {  //IPv6
1530       ipHeader6 = (struct ip6_hdr *)ipPacket;
1531       if (ipHeader6->ip6_dst.s6_addr[0] != 0xff) {     //Multicast
1532         return;               //not multicast
1533       }
1534
1535       if (ipHeader6->ip6_nxt != SOL_UDP) {
1536         /* Not UDP */
1537         OLSR_DEBUG(LOG_PLUGINS, "NON UDP PACKET\n");
1538         return;               /* for */
1539       }
1540     }                         //END IPV6
1541     else {
1542       return;                 //Is not IP packet
1543     }
1544
1545     // send the packet to OLSR forward mechanism
1546     // SendOBAMPData(&tmp->neighbor_ip_addr.v6,ipPacket,nBytes);
1547   }                           /* if (pktAddr.sll_pkttype == ...) */
1548 }                               /* EncapFlowInObamp */
1549
1550 //This function is called from olsrd_plugin.c and adds to the list the interfaces specified in the configuration file to sniff multicast traffic
1551 int
1552 AddObampSniffingIf(const char *ifName,
1553                    void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
1554 {
1555
1556   struct ObampSniffingIf *ifToAdd;
1557
1558   OLSR_DEBUG(LOG_PLUGINS, "AddObampSniffingIf");
1559
1560
1561   assert(ifName != NULL);
1562
1563   ifToAdd = olsr_malloc(sizeof(struct ObampSniffingIf), "OBAMPSniffingIf");
1564
1565   strncpy(ifToAdd->ifName, ifName, 16); //TODO: 16 fix this
1566   ifToAdd->ifName[15] = '\0';   /* Ensures null termination */
1567
1568   OLSR_DEBUG(LOG_PLUGINS, "Adding interface to list");
1569
1570   list_add_tail(&ListOfObampSniffingIf, &(ifToAdd->list));
1571
1572   OLSR_DEBUG(LOG_PLUGINS, "Adding if %s to list of ObampSniffingIfaces", ifToAdd->ifName);
1573
1574   return 0;
1575 }
1576
1577
1578 int
1579 PreInitOBAMP(void)
1580 {
1581   list_init_head(&ListOfObampSniffingIf);
1582   return 0;
1583
1584 }
1585
1586 //Start here !!
1587
1588 int
1589 InitOBAMP(void)
1590 {
1591 #if !defined(REMOVE_LOG_DEBUG)
1592   struct ipaddr_str buf;
1593 #endif
1594
1595 //Structs necessary for timers
1596
1597   struct olsr_timer_entry *OBAMP_alive_timer;
1598   struct olsr_timer_entry *purge_nodes_timer;
1599   struct olsr_timer_entry *mesh_create_timer;
1600   struct olsr_timer_entry *tree_create_timer;
1601   struct olsr_timer_entry *outer_tree_create_timer;
1602   struct olsr_timer_entry *unsolicited_tree_destroy_timer;
1603
1604
1605
1606   struct olsr_timer_info *OBAMP_alive_gen_timer_cookie = NULL;
1607   struct olsr_timer_info *purge_nodes_timer_cookie = NULL;
1608   struct olsr_timer_info *mesh_create_timer_cookie = NULL;
1609   struct olsr_timer_info *tree_create_timer_cookie = NULL;
1610   struct olsr_timer_info *outer_tree_create_timer_cookie = NULL;
1611   struct olsr_timer_info *unsolicited_tree_destroy_timer_cookie = NULL;
1612
1613   if (olsr_cnf->ip_version == AF_INET6) {
1614     OLSR_ERROR(LOG_PLUGINS, "OBAMP does not support IPv6 at the moment.");
1615     return 1;
1616   }
1617
1618 //Setting OBAMP node state
1619   myState = olsr_malloc(sizeof(struct ObampNodeState), "OBAMPNodeState");
1620   myState->iamcore = 1;
1621   myState->TreeHeartBeat = 0;
1622   myState->TreeRequestDelay = 0;
1623   memcpy(&myState->myipaddr.v4, &olsr_cnf->router_id, olsr_cnf->ipsize);
1624   myState->CoreAddress = myState->myipaddr;
1625
1626   myState->DataSequenceNumber = 0;
1627   myState->TreeCreateSequenceNumber = 0;
1628   myState->tree_req_sn = 0;     //TODO: start from random number ?
1629
1630   memset(&myState->ParentId.v4, 0, sizeof(myState->ParentId.v4));
1631   memset(&myState->OldParentId.v4, 1, sizeof(myState->OldParentId.v4));
1632
1633   OLSR_DEBUG(LOG_PLUGINS, "SETUP: my IP - %s", ip4_to_string(&buf, myState->myipaddr.v4));
1634
1635   list_init_head(&ListOfObampNodes);
1636
1637 //OLSR cookies stuff for timers
1638   OBAMP_alive_gen_timer_cookie =
1639       olsr_timer_add("OBAMP Alive Generation", &obamp_alive_gen, true);
1640   purge_nodes_timer_cookie =
1641       olsr_timer_add("purge nodes Generation", &purge_nodes, true);
1642   mesh_create_timer_cookie =
1643       olsr_timer_add("mesh create Generation", &mesh_create, true);
1644   tree_create_timer_cookie =
1645       olsr_timer_add("tree create Generation", &tree_create, true);
1646   outer_tree_create_timer_cookie =
1647       olsr_timer_add("outer tree create Generation", &outer_tree_create, true);
1648   unsolicited_tree_destroy_timer_cookie =
1649       olsr_timer_add("tree destroy Generation", &unsolicited_tree_destroy, true);
1650
1651
1652 //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
1653   olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
1654
1655 // start to send alive messages to appear in other joined lists
1656   OBAMP_alive_timer =
1657     olsr_timer_start(OBAMP_ALIVE_EIVAL * MSEC_PER_SEC, OBAMP_JITTER, NULL,
1658                      OBAMP_alive_gen_timer_cookie);
1659
1660 // start timer to purge nodes from list in softstate fashion
1661   purge_nodes_timer =
1662     olsr_timer_start(_Texpire_timer_ * MSEC_PER_SEC, OBAMP_JITTER, NULL,
1663                      purge_nodes_timer_cookie);
1664
1665 //start timer to create mesh
1666   mesh_create_timer =
1667     olsr_timer_start(OBAMP_MESH_CREATE_IVAL * MSEC_PER_SEC, OBAMP_JITTER, NULL,
1668                      mesh_create_timer_cookie);
1669
1670 //start timer for tree create procedure
1671   tree_create_timer =
1672     olsr_timer_start(OBAMP_TREE_CREATE_IVAL * MSEC_PER_SEC, OBAMP_JITTER, NULL,
1673                      tree_create_timer_cookie);
1674
1675 //start timer for tree create procedure
1676   outer_tree_create_timer =
1677     olsr_timer_start(OBAMP_OUTER_TREE_CREATE_IVAL * MSEC_PER_SEC, OBAMP_JITTER, NULL,
1678                      tree_create_timer_cookie);
1679
1680 //start timer for tree create procedure
1681   unsolicited_tree_destroy_timer =
1682     olsr_timer_start(30 * MSEC_PER_SEC, OBAMP_JITTER, NULL,
1683                      unsolicited_tree_destroy_timer_cookie);
1684
1685 //Create udp server socket for OBAMP signalling and register it to the scheduler
1686   OLSR_DEBUG(LOG_PLUGINS, "Launch Udp Servers");
1687   if (UdpServer() < 0) {
1688     OLSR_DEBUG(LOG_PLUGINS, "Problem in Launch Udp Servers");
1689
1690   };
1691
1692 //Creates a socket for sniffing multicast traffic and registers it to the scheduler
1693   CreateObampSniffingInterfaces();
1694
1695   return 0;
1696 }
1697
1698 /* -------------------------------------------------------------------------
1699  * Function   : CloseOBAMP
1700  * Description: Close the OBAMP plugin and clean up
1701  * Input      : none
1702  * Output     : none
1703  * Return     : none
1704  * Data Used  :
1705  * ------------------------------------------------------------------------- */
1706 void
1707 CloseOBAMP(void)
1708 {
1709 //do something here
1710 }