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