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