Reduced dependency on threads by moving towards times (+ regression-testing) and...
[olsrd.git] / lib / cl_roam / src / cl_roam.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 #include "cl_roam.h"
43 #include "olsr_types.h"
44 #include "ipcalc.h"
45 #include "scheduler.h"
46 #include "olsr.h"
47 #include "olsr_cookie.h"
48 #include "olsr_ip_prefix_list.h"
49 #include "olsr_logging.h"
50
51 #include <stdio.h>
52 #include <string.h>
53 #include <stdlib.h>
54 #include <net/route.h>
55 #include <unistd.h>
56 #include <errno.h>
57 #include <pthread.h>
58 #include "neighbor_table.h"
59 #include "olsr.h"
60 #include "olsr_cfg.h"
61 #include "interfaces.h"
62 #include "olsr_protocol.h"
63 #include "net_olsr.h"
64 #include "link_set.h"
65 #include "ipcalc.h"
66 #include "lq_plugin.h"
67 #include "olsr_cfg_gen.h"
68 #include "common/string.h"
69 #include "olsr_ip_prefix_list.h"
70 #include "olsr_logging.h"
71 #include <netinet/in.h>
72 #include <sys/socket.h>
73 #include <arpa/inet.h>
74
75 #define PLUGIN_INTERFACE_VERSION 5
76
77 static int has_inet_gateway;
78 static struct olsr_cookie_info *event_timer_cookie1;
79 static struct olsr_cookie_info *event_timer_cookie2;
80 static union olsr_ip_addr gw_netmask;
81
82 /**
83  * Plugin interface version
84  * Used by main olsrd to check plugin interface version
85  */
86 int
87 olsrd_plugin_interface_version(void)
88 {
89   return PLUGIN_INTERFACE_VERSION;
90 }
91
92 static const struct olsrd_plugin_parameters plugin_parameters[] = {
93 };
94
95
96
97 typedef struct { 
98         struct in_addr ip;
99         u_int64_t mac;
100         struct in_addr from_node;
101         char is_announced;
102         float last_seen;
103         pthread_t ping_thread;
104         pthread_t ping_thread_add;
105         struct olsr_cookie_info *arping_timer_cookie;
106         char ping_thread_done;
107         struct timer_entry *arping_timer;
108  } guest_client;
109
110
111
112 typedef struct {
113         guest_client *client;
114         struct client_list *list;
115 } client_list;
116
117
118
119 void update_routes_now()
120 {
121         //Recalculate our own routing table RIGHT NOW
122
123           OLSR_INFO(LOG_PLUGINS, "Forcing recalculation of routing-table\n");
124
125     //sets timer to zero
126
127
128     spf_backoff_timer = NULL;
129     ///printf("timer stopped\n");
130     //actual calculation
131     olsr_calculate_routing_table();
132     //printf("updated\n");
133 }
134
135
136 client_list *list;
137 struct interface *ifn;
138
139
140 void ping(guest_client *);
141
142 void
143 olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
144 {
145   *params = plugin_parameters;
146   *size = ARRAYSIZE(plugin_parameters);
147 }
148
149
150
151
152
153
154 guest_client * get_client_by_ip(struct in_addr ip) {
155   if (list!=NULL && list->client!=NULL) {
156
157     if (strcmp(inet_ntoa(list->client->ip), inet_ntoa(ip))==0)
158         return list->client;
159     else
160         return get_client_by_ip(ip);
161   }
162   else
163           return NULL;
164 }
165
166
167
168 void
169 olsr_parser(struct olsr_message *msg, struct interface *in_if __attribute__ ((unused)),
170     union olsr_ip_addr *ipaddr, enum duplicate_status status __attribute__ ((unused)))
171 {
172         const uint8_t *curr;
173 // my MessageType
174   if (msg->type != 134) {
175           printf("recieved something else\n");
176     return;
177   }
178   OLSR_INFO(LOG_PLUGINS, "Recieved roaming-messagetype\n");
179   curr = msg->payload;
180   struct in_addr ip;
181   pkt_get_ipaddress(&curr, &ip);
182
183
184   guest_client * guest;
185
186   guest=get_client_by_ip(ip);
187
188
189
190   if (guest!=NULL) {
191           if ((guest->is_announced)!=0) {
192                   OLSR_INFO(LOG_PLUGINS, "Having to revoke announcement for %s\n", inet_ntoa(guest->ip));
193                   guest->is_announced=0;
194                   guest->last_seen=30.0;
195
196                   ip_prefix_list_remove(&olsr_cnf->hna_entries, &(guest->ip), olsr_netmask_to_prefix(&gw_netmask), olsr_cnf->ip_version);
197                   char route_command[50];
198                   snprintf(route_command, sizeof(route_command), "route del %s dev ath0 metric 0", inet_ntoa(guest->ip));
199                   system(route_command);
200                   single_hna(&ip, 0);
201
202                   }
203          // else
204                 //  printf("Not revoking \n");
205   }
206   //else
207         //  printf("Not revoking\n");
208
209
210
211
212   update_routes_now();
213
214
215 }
216
217
218
219
220
221
222
223
224
225 /**
226  * Initialize plugin
227  * Called after all parameters are passed
228  */
229 int
230 olsrd_plugin_init(void)
231 {
232
233
234   
235   list=(client_list*)malloc( sizeof(client_list) );
236
237
238
239   OLSR_INFO(LOG_PLUGINS, "OLSRD automated Client Roaming Plugin\n");
240
241
242   gw_netmask.v4.s_addr = inet_addr("255.255.255.255");
243
244   has_inet_gateway = 0;
245
246
247   /* create the cookie */
248   event_timer_cookie1 = olsr_alloc_cookie("cl roam: Event1", OLSR_COOKIE_TYPE_TIMER);
249   event_timer_cookie2 = olsr_alloc_cookie("cl roam: Event2", OLSR_COOKIE_TYPE_TIMER);
250
251   /* Register the GW check */
252   olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, &olsr_event1, NULL, event_timer_cookie1);
253   olsr_start_timer(10 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, &olsr_event2, NULL, event_timer_cookie2);
254
255
256   /* register functions with olsrd */
257   // somehow my cool new message.....
258   olsr_parser_add_function(&olsr_parser, 134);
259
260
261
262   return 1;
263 }
264
265
266
267 int ping_thread(void* guest) {
268
269         guest_client * target = (guest_client *) guest;
270     target->ping_thread_done=0;
271
272     char ping_command[50];
273
274     snprintf(ping_command, sizeof(ping_command), "arping -I ath0 -w 1 -c 1 -q %s", inet_ntoa(target->ip));
275     //printf("%s\n",ping_command);
276     int result = system(ping_command);
277     target->ping_thread_done=1;
278     //printf("ping thread finished\n");
279     return result;
280
281 }
282
283
284
285 void ping_thread_infinite(guest_client * target)
286 {
287     char ping_command[50];
288
289     while (1) {
290                 snprintf(ping_command, sizeof(ping_command), "arping -I ath0 -q -c 10 %s", inet_ntoa(target->ip));
291                 system(ping_command);
292                 pthread_testcancel();
293     }
294
295 }
296
297
298
299 void ping_infinite(guest_client * target)
300 {
301         int rc;
302         pthread_t thread;
303         if (target->ping_thread==NULL) {
304                 rc = pthread_create(&thread, NULL, ping_thread_infinite, (void *) target   );
305                 if (rc){
306                    printf("ERROR; return code from pthread_create() is %d\n", rc);
307                    exit(-1);
308                 }
309                 target->ping_thread=thread;
310                 OLSR_INFO(LOG_PLUGINS, "Set up ping-thread for %s\n", inet_ntoa(target->ip));
311         }
312         else
313                 OLSR_INFO(LOG_PLUGINS, "Ping-thread for %s already exists!\n", inet_ntoa(target->ip));
314 }
315
316
317
318
319
320
321
322
323 struct olsr_message msg;
324
325 void
326 check_ping_result(void *foo )
327 {
328         guest_client * host = (guest_client *) foo;
329
330         if (! host->ping_thread_done) {
331                 OLSR_DEBUG(LOG_PLUGINS, "Ping-thread for %s not finished\n", inet_ntoa(host->ip));
332
333         }
334         else {
335                 olsr_stop_timer(host->arping_timer);
336                 int ping_res;
337                 pthread_join(host->ping_thread_add, &ping_res);
338                 host->arping_timer=NULL;
339                 host->ping_thread_done=0;
340                 if(ping_res==0) {
341                         OLSR_INFO(LOG_PLUGINS, "Adding Route for %s\n", inet_ntoa(host->ip));
342
343                         ip_prefix_list_add(&olsr_cnf->hna_entries, &(host->ip), olsr_netmask_to_prefix(&gw_netmask));
344                         host->is_announced=1;
345
346
347                         char route_command[50];
348                         snprintf(route_command, sizeof(route_command), "route add %s dev ath0 metric 0", inet_ntoa(host->ip));
349                         system(route_command);
350
351
352
353
354                         spread_host(host);
355                         //This really big time will be overwritten by the next normal hna-announcement
356                         single_hna(&host->ip, -1);
357
358
359                         //Append to buffer, will be send at some time. In case it didn't arrive at the old master
360                         spread_host(host);
361
362
363
364                 }
365                 else {
366                   host->last_seen+=0.5;
367                   check_for_route(host);
368         }
369         }
370
371 }
372
373
374
375
376
377
378
379 void check_for_route(guest_client * host)
380 {
381 //printf("%f, %i, %x\n",host->last_seen , host->is_announced  ,host->ping_thread_add );
382   if (host->last_seen < 5.0 && ! host->is_announced  && host->arping_timer==NULL) {
383
384           //printf("maybe add something\n");
385           if (host->arping_timer_cookie==NULL)
386                   host->arping_timer_cookie = olsr_alloc_cookie("cl roam: Maybe add something", OLSR_COOKIE_TYPE_TIMER);
387           //printf("timer started\n");
388           host->arping_timer = olsr_start_timer(250, 5, OLSR_TIMER_PERIODIC, &check_ping_result, host, host->arping_timer_cookie);
389           int rc = pthread_create(&(host->ping_thread_add), NULL, ping_thread, (void *)host);
390
391
392
393   } else if ((host->last_seen > 20.0) &&  host->is_announced) {
394       OLSR_INFO(LOG_PLUGINS, "Removing Route for %s\n", inet_ntoa(host->ip));
395       ip_prefix_list_remove(&olsr_cnf->hna_entries, &(host->ip), olsr_netmask_to_prefix(&gw_netmask), olsr_cnf->ip_version);
396                 char route_command[50];
397                 snprintf(route_command, sizeof(route_command), "route del %s dev ath0 metric 0", inet_ntoa(host->ip));
398                 system(route_command);
399       host->is_announced=0;
400 }
401 }
402
403 void check_client_list(client_list * clist) {
404   if (clist!=NULL && clist->client!=NULL) {
405
406     //ping(clist->client);
407           if(clist->client->is_announced==1 || clist->client->ping_thread!=NULL) {
408                   if( ! check_if_associcated(clist->client)) {
409                           if(clist->client->is_announced==1) {
410                                   clist->client->last_seen+=5;
411                           }
412                           if (clist->client->ping_thread!=NULL) {
413                                   //printf("attempting to kill ping-thread\n");
414                                   pthread_detach(clist->client->ping_thread);
415                                   //pthread_kill(clist->client->ping_thread, 1);
416                                   //pthread_cancel(clist->client->ping_thread);
417                                   pthread_cancel(clist->client->ping_thread);
418                                   //printf("killed ping-thread\n");
419                                   OLSR_INFO(LOG_PLUGINS, "Killed ping-thread for %s\n", inet_ntoa(clist->client->ip));
420                                   clist->client->ping_thread=NULL;
421                           }
422                   }
423           }
424
425
426     check_for_route(clist->client);
427     check_client_list(clist->list);
428   }
429 }
430
431
432
433 guest_client * get_client_by_mac(client_list * clist, u_int64_t mac) {
434   if (clist!=NULL && clist->client!=NULL) {
435
436     if (clist->client->mac == mac)
437         return clist->client;
438     else
439         return get_client_by_mac(clist->list, mac);
440   }
441   else
442           return NULL;
443 }
444
445
446
447
448
449
450
451 int ip_is_in_guest_list(client_list * list, guest_client * host) {
452 if (list==NULL)
453   return 0;
454 if (list->client==NULL)
455   return 0;
456 else if (inet_lnaof(list->client->ip) == inet_lnaof(host->ip))
457   return 1;
458 else
459   return ip_is_in_guest_list(list->list, host);
460 }
461
462
463 void check_local_leases(client_list * clist){
464   check_leases(clist,"/var/dhcp.leases" , 1.0);
465 }
466
467
468 void check_leases(client_list * clist, char file[], float def_last_seen) {
469           FILE * fp = fopen(file, "r");
470           if(fp == NULL) {
471                   printf("failed to open %s\n", file);
472                   return EXIT_FAILURE;
473               }
474           char s1[50];
475           char s2[50];
476           char s3[50];
477           long long int one, two, three, four, five, six;
478
479           while (1) {
480                   int parse = fscanf (fp, "%s %llx:%llx:%llx:%llx:%llx:%llx %s %*s %*s\n", s1, &one, &two, &three, &four, &five, &six, s3);
481             if (parse==EOF)
482               break;
483             if(parse==8) {
484             guest_client* user;
485             //printf ("String 3 = %s\n", s3);
486             user = (guest_client*)malloc( sizeof(guest_client) );
487             inet_aton(s3, &(user->ip));
488             user->mac= six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40;
489             user->last_seen=def_last_seen;
490             user->is_announced=0;
491             user->ping_thread=NULL;
492             //printf("last seen on Add %f\n",user->last_seen);
493             add_client_to_list(clist, user);
494
495         }
496           }
497           fclose(fp);
498
499
500         }
501
502
503
504
505 void check_remote_leases(client_list * clist){
506           FILE * fp = fopen("/tmp/otherclient", "r");
507           if(fp == NULL) {
508                   printf("failed to open %s\n", "/tmp/otherclient");
509                   return EXIT_FAILURE;
510               }
511           FILE * my_leases =fopen ("/var/dhcp.leases", "a");
512           if(my_leases == NULL) {
513                   printf("failed to open %s\n","/var/dhcp.leases");
514                   return EXIT_FAILURE;
515               }
516           char s1[50];
517           char s2[50];
518           char s3[50];
519           long long int one, two, three, four, five, six;
520
521           while (1) {
522                   int parse = fscanf (fp, "%s %llx:%llx:%llx:%llx:%llx:%llx %s %*s %*s\n", s1, &one, &two, &three, &four, &five, &six, s3);
523             if (parse==EOF)
524               break;
525             if(parse==8) {
526             guest_client* user;
527             //printf ("String 3 = %s\n", s3);
528             user = (guest_client*)malloc( sizeof(guest_client) );
529             inet_aton(s3, &(user->ip));
530             user->mac= six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40;
531             user->last_seen=30.0;
532             user->is_announced=0;
533             user->ping_thread=NULL;
534             //printf("last seen on Add %f\n",user->last_seen);
535
536             if (!(ip_is_in_guest_list(clist,  user))) {
537
538                 char leases[80];
539
540                 // Why the fuck cant I do it in one step!?
541                  snprintf(leases, sizeof(leases), "%s %llx:%llx:%llx:%llx:%llx:%llx", s1, one, two, three, four, five, six);
542                  snprintf(leases, sizeof(leases), "%s %s * *\n", leases, s3);
543                 //printf(leases);
544                 fprintf(my_leases, leases);
545             }
546
547
548             add_client_to_list(clist, user);
549
550         }
551           }
552           fclose(fp);
553           fclose(my_leases);
554
555
556         }
557
558
559
560
561
562 int check_if_associcated(guest_client *client)
563 {
564   FILE * fp = fopen("/proc/net/madwifi/ath0/associated_sta", "r");
565   if(fp == NULL) {
566           printf("failed to open %s\n", "/proc/net/madwifi/ath0/associated_sta");
567           return EXIT_FAILURE;
568       }
569   //FILE * fp = fopen("/home/raphael/tmp/leases", "r");
570   char s1[50];
571   char s2[50];
572   char s3[50];
573   int rssi;
574   float last_rx;
575   int parse;
576   uint64_t mac;
577   long long int one, two, three, four, five, six;
578
579   while (1) {
580     parse = fscanf (fp, "macaddr: <%llx:%llx:%llx:%llx:%llx:%llx>\n", &one, &two, &three, &four, &five, &six);
581     if (parse==EOF || parse!=6)
582       break;
583     mac = six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40;
584     //printf ("am at %llx\n", mac);
585     if (mac==client->mac) {
586       //printf("found it!\n");
587       fclose(fp);
588       return 1;
589     }
590     parse = fscanf (fp, " rssi %s\n", s2);
591     if (parse==EOF)
592           break;
593     parse = fscanf (fp, " last_rx %f\n", &last_rx);
594     if (parse==EOF)
595           break;
596   }
597
598   fclose(fp);
599
600   return 0;
601
602 }
603
604
605
606
607
608
609
610
611 // Will be handy to identify when a client roamed to us. Not used yet.
612 void check_associations(client_list * clist){
613   FILE * fp = fopen("/proc/net/madwifi/ath0/associated_sta", "r");
614   if(fp == NULL) {
615            printf("failed to open %s\n", "/proc/net/madwifi/ath0/associated_sta");
616            return EXIT_FAILURE;
617        }
618   //FILE * fp = fopen("/home/raphael/tmp/leases", "r");
619   char s1[50];
620   char s2[50];
621   char s3[50];
622   int rssi;
623   float last_rx;
624   int parse;
625
626   long long int one, two, three, four, five, six;
627
628   while (1) {
629     parse = fscanf (fp, "macaddr: <%llx:%llx:%llx:%llx:%llx:%llx>\n", &one, &two, &three, &four, &five, &six);
630     if (parse==EOF || parse!=6)
631       break;
632     uint64_t mac = six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40;
633     //printf ("macaddr: %llx\n", mac);
634     parse = fscanf (fp, " rssi %s\n", s2);
635     if (parse==EOF)
636           break;
637     //printf ("rssi = %s\n", s2);
638     parse = fscanf (fp, " last_rx %f\n", &last_rx);
639     if (parse==EOF)
640           break;
641     //printf ("last_rx = %f\n", last_rx);
642     guest_client* node = get_client_by_mac(clist, mac);
643     if (node!=NULL) {
644         //printf("Sichtung!\n");
645         node->last_seen=last_rx;
646         if(node->ping_thread==NULL) {
647                 ping_infinite(node);
648                         }
649     }
650
651   }
652   fclose(fp);
653
654
655 }
656
657
658
659
660
661
662
663
664
665 void add_client_to_list(client_list * clist, guest_client * host) {
666   if (ip_is_in_guest_list(clist,  host)) {
667     free(host);
668   }
669   else {
670     if (clist->client!=NULL) {
671       client_list * this_one;
672       this_one = (client_list *)malloc( sizeof(client_list) );
673       this_one->client = host;
674       this_one->list=clist->list;
675       clist->list=this_one;
676       OLSR_INFO(LOG_PLUGINS, "Keeping track of %s\n", inet_ntoa(host->ip));
677     } else {
678       clist->client=host;
679       OLSR_INFO(LOG_PLUGINS, "Keeping track of %s\n", inet_ntoa(host->ip));
680     }
681     ping_infinite(host);
682   }
683 }
684
685
686
687
688
689 void check_for_new_clients(client_list * clist) {
690     check_local_leases(clist);
691     check_associations(clist);
692 }
693
694
695
696 void check_neighbour_host(void* neighbour) {
697         struct nbr_entry *nbr = (struct nbr_entry*) neighbour;
698         union olsr_ip_addr foobar = nbr->nbr_addr;
699
700         char wget_command[70];
701
702
703         snprintf(wget_command, sizeof(wget_command), "wget -q -O /tmp/otherclient http://%s/dhcp.leases", inet_ntoa(foobar.v4));
704         if (system(wget_command)==0){
705
706         check_remote_leases(list);
707         }
708 }
709
710
711
712
713
714
715
716
717
718
719 void
720 spread_host(guest_client * host) {
721   struct interface *ifp;
722   struct ip_prefix_entry *h;
723   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE] __attribute__ ((aligned));
724   uint8_t *curr = msg_buffer;
725   uint8_t *length_field, *last;
726   bool sendHNA = false;
727
728   OLSR_INFO(LOG_PACKET_CREATION, "Building HNA\n-------------------\n");
729
730   // My message Type 134:
731   pkt_put_u8(&curr, 134);
732   // hna-validity
733   pkt_put_reltime(&curr, 20000);
734
735   length_field = curr;
736   pkt_put_u16(&curr, 0); /* put in real messagesize later */
737
738   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
739
740   // TTL
741   pkt_put_u8(&curr, 2);
742   pkt_put_u8(&curr, 0);
743   pkt_put_u16(&curr, get_msg_seqno());
744
745   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize;
746
747
748
749
750 // Actual message
751         pkt_put_ipaddress(&curr, &(host->ip));
752
753
754
755         //Put in Message size
756   pkt_put_u16(&length_field, curr - msg_buffer);
757
758   OLSR_FOR_ALL_INTERFACES(ifp) {
759             if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
760               net_output(ifp);
761               set_buffer_timer(ifp);
762             }
763         // buffer gets pushed out in single_hna, or at flush-time
764     net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
765   } OLSR_FOR_ALL_INTERFACES_END(ifp)
766
767
768 }
769
770
771
772
773
774
775
776
777
778 // sends packet immedeately!
779 void
780 single_hna(struct in_addr * ip, uint32_t time) {
781           //printf("single hna %x with time %i\n",*ip, time);
782
783
784
785
786   struct interface *ifp;
787   struct ip_prefix_entry *h;
788   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE] __attribute__ ((aligned));
789   uint8_t *curr = msg_buffer;
790   uint8_t *length_field, *last;
791   bool sendHNA = false;
792
793   OLSR_INFO(LOG_PACKET_CREATION, "Building HNA\n-------------------\n");
794
795   // My message Type 134:
796   pkt_put_u8(&curr, HNA_MESSAGE);
797   // hna-validity
798   pkt_put_reltime(&curr, time);
799
800   length_field = curr;
801   pkt_put_u16(&curr, 0); /* put in real messagesize later */
802
803   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
804
805   // TTL
806   pkt_put_u8(&curr, 2);
807   pkt_put_u8(&curr, 0);
808   pkt_put_u16(&curr, get_msg_seqno());
809
810   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize;
811
812
813
814   struct in_addr subnet;
815           inet_aton("255.255.255.255", &subnet);
816         pkt_put_ipaddress(&curr, ip);
817         pkt_put_ipaddress(&curr, &subnet);
818
819
820   pkt_put_u16(&length_field, curr - msg_buffer);
821
822
823
824
825   OLSR_FOR_ALL_INTERFACES(ifp) {
826     net_output(ifp);
827     net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
828     net_output(ifp);
829     set_buffer_timer(ifp);
830   } OLSR_FOR_ALL_INTERFACES_END(ifp)
831 }
832
833
834
835
836
837
838
839
840
841
842 void
843 olsr_event1(void *foo )
844 {
845         check_for_new_clients(list);
846     check_client_list(list);
847 }
848
849
850 void
851 olsr_event2(void *foo )
852 {
853         struct nbr_entry *nbr;
854
855     OLSR_FOR_ALL_NBR_ENTRIES(nbr) {
856         int rc;
857         pthread_t thread;
858         rc = pthread_create(&thread, NULL, check_neighbour_host, (void *) nbr   );
859         if (rc){
860            printf("ERROR; return code from pthread_create() is %d\n", rc);
861            exit(-1);
862                 }
863
864         }OLSR_FOR_ALL_NBR_ENTRIES_END();
865 }
866
867
868
869