Namespace cleanup of scheduler, remove "polling" sockets
[olsrd.git] / lib / cl_roam / src / cl_roam.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include "cl_roam.h"
42 #include "olsr_types.h"
43 #include "ipcalc.h"
44 #include "scheduler.h"
45 #include "olsr.h"
46 #include "olsr_memcookie.h"
47 #include "olsr_ip_prefix_list.h"
48 #include "olsr_logging.h"
49 #include "os_system.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 <parser.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_timer_info *event_timer_info1;
79 static struct olsr_timer_info *event_timer_info2;
80 static struct olsr_timer_info *arping_timer_info;
81 static union olsr_ip_addr gw_netmask;
82
83 static void check_ping_result(void *foo);
84
85 /**
86  * Plugin interface version
87  * Used by main olsrd to check plugin interface version
88  */
89 int olsrd_plugin_interface_version(void) {
90   return PLUGIN_INTERFACE_VERSION;
91 }
92
93 static const struct olsrd_plugin_parameters plugin_parameters[] = { };
94
95 struct guest_client {
96   union olsr_ip_addr ip;
97   u_int64_t mac;
98   struct in_addr from_node;
99   char is_announced;
100   float last_seen;
101   pthread_t ping_thread;
102   pthread_t ping_thread_add;
103   struct olsr_memcookie_info *arping_timer_cookie;
104   char ping_thread_done;
105   struct olsr_timer_entry *arping_timer;
106   int remaing_announcements;
107   //who is in charge of this client
108   union olsr_ip_addr master_ip;
109 };
110
111 struct client_list {
112   struct guest_client *client;
113   struct client_list *list;
114 };
115
116 //Declaration of all functions
117 static void check_client_list(struct client_list * clist);
118 static int ip_is_in_guest_list(struct client_list * list, struct guest_client * host);
119 static void check_remote_leases(struct client_list * clist);
120 static int check_if_associcated(struct guest_client *client);
121 static void check_associations(struct client_list * clist);
122 static void add_client_to_list(struct client_list * clist, struct guest_client * host);
123 static void check_for_new_clients(struct client_list * clist);
124 static void* check_neighbour_host(void* neighbour);
125 static void spread_host(struct guest_client * host);
126 static void single_hna(union olsr_ip_addr * ip, uint32_t vtime);
127 static void olsr_event1(void *foo __attribute__ ((unused)) );
128 static struct guest_client * get_client_by_ip(union olsr_ip_addr ip);
129 #if 0
130 static void *
131 relay_spread_host(union olsr_ip_addr host_ip, union olsr_ip_addr master_ip, uint8_t TTL, uint8_t Hopcount);
132 #endif
133 static void
134     olsr_parser(struct olsr_message *msg, struct interface *in_if __attribute__ ((unused)), union olsr_ip_addr *ipaddr,
135         enum duplicate_status status);
136 static void check_leases(struct client_list * clist, const char *file, float def_last_seen);
137 static void check_local_leases(struct client_list * clist);
138 static struct guest_client * get_client_by_mac(struct client_list * clist, u_int64_t mac);
139 static void update_routes_now(void);
140 static void check_for_route(struct guest_client * host);
141
142 static void olsr_event1(void *foo __attribute__ ((unused)) );
143 static void olsr_event2(void *foo  __attribute__ ((unused)));
144
145 void update_routes_now(void) {
146   //Recalculate our own routing table RIGHT NOW
147
148   OLSR_INFO(LOG_PLUGINS, "Forcing recalculation of routing-table\n");
149
150   //actual calculation
151   olsr_calculate_routing_table(true);
152   //printf("updated\n");
153 }
154
155 struct client_list *list;
156 struct interface *ifn;
157
158 void ping(struct guest_client *);
159
160 void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size) {
161   *params = plugin_parameters;
162   *size = ARRAYSIZE(plugin_parameters);
163 }
164
165 struct guest_client * get_client_by_ip(union olsr_ip_addr ip) {
166   if (list != NULL && list->client != NULL) {
167
168     if (strcmp(inet_ntoa(list->client->ip.v4), inet_ntoa(ip.v4)) == 0)
169       return list->client;
170     else
171       return get_client_by_ip(ip);
172   } else
173     return NULL;
174 }
175
176 #if 0
177 static void *
178 relay_spread_host(union olsr_ip_addr host_ip, union olsr_ip_addr master_ip, uint8_t TTL, uint8_t Hopcount) {
179   struct interface *ifp;
180   struct list_iterator iterator;
181   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE] __attribute__ ((aligned));
182   uint8_t *curr = msg_buffer;
183   uint8_t *length_field, *last;
184
185   OLSR_INFO(LOG_PACKET_CREATION, "Building Message Relay\n-------------------\n");
186
187   // My message Type 134:
188   pkt_put_u8(&curr, 134);
189   // validity
190   pkt_put_reltime(&curr, 20000);
191
192   length_field = curr;
193   pkt_put_u16(&curr, 0); /* put in real messagesize later */
194
195   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
196
197   // TTL
198   pkt_put_u8(&curr, TTL - 1);
199   pkt_put_u8(&curr, Hopcount + 1);
200   pkt_put_u16(&curr, get_msg_seqno());
201
202   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize;
203
204   if (TTL < 1) {
205     OLSR_DEBUG(LOG_PLUGINS, "Not relaying, TTL exceded");
206     return NULL;
207   }
208
209   // Actual message
210   //first IP to announce
211   pkt_put_ipaddress(&curr, &host_ip);
212   // second: announcing IP
213   pkt_put_ipaddress(&curr, &master_ip);
214
215   //Put in Message size
216   pkt_put_u16(&length_field, curr - msg_buffer);
217
218   OLSR_FOR_ALL_INTERFACES(ifp, iterator) {
219     if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
220       net_output(ifp);
221       set_buffer_timer(ifp);
222     }
223     // buffer gets pushed NOW
224     net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
225     net_output(ifp);
226     set_buffer_timer(ifp);
227   }
228
229   OLSR_INFO(LOG_PLUGINS, "Relayed some foo!");
230
231   return NULL;
232 }
233 #endif
234
235 void olsr_parser(struct olsr_message *msg, struct interface *in_if __attribute__ ((unused)), union olsr_ip_addr *ipaddr,
236     enum duplicate_status status __attribute__ ((unused))) {
237   const uint8_t *curr;
238   union olsr_ip_addr ip, master_ip;
239   struct guest_client * guest;
240
241   // my MessageType
242   if (msg->type != 134) {
243     printf("recieved something else\n");
244     return;
245   }
246   OLSR_DEBUG(LOG_PLUGINS, "Recieved roaming-messagetype from %s\n", inet_ntoa(ipaddr->v4));
247   curr = msg->payload;
248   pkt_get_ipaddress(&curr, &ip);
249   pkt_get_ipaddress(&curr, &master_ip);
250
251   guest = get_client_by_ip(ip);
252
253   // Forward it --start--
254   /*
255    if (status == DUPLICATE_OLSR_MESSAGE) {
256    OLSR_INFO(LOG_PLUGINS, "Not relaying, duplicate");
257    }
258    else {
259    relay_spread_host(ip, master_ip, msg->ttl, msg->hopcnt);
260    }
261    */
262
263   // Forwarding --end--
264
265   if (guest != NULL) {
266     if ((guest->is_announced) != 0) {
267       char route_command[50];
268       int ret;
269
270       OLSR_INFO(LOG_PLUGINS, "Having to revoke announcement for %s\n", inet_ntoa(guest->ip.v4));
271       guest->is_announced = 0;
272       guest->last_seen = 90.0;
273       guest->remaing_announcements = 0;
274
275       ip_prefix_list_remove(&olsr_cnf->hna_entries, &(guest->ip), olsr_netmask_to_prefix(&gw_netmask),
276           olsr_cnf->ip_version);
277       snprintf(route_command, sizeof(route_command), "route del %s dev ath0 metric 0", inet_ntoa(guest->ip.v4));
278       if ((ret = system(route_command))) {
279         OLSR_WARN(LOG_PLUGINS, "cl_roam: Warning, system '%s' returned %d\n", route_command, ret);
280       }
281       single_hna(&ip, 0);
282     }
283   }
284
285   if (guest != NULL) {
286     OLSR_DEBUG(LOG_PLUGINS, "Old master: %s\n", inet_ntoa(guest->master_ip.v4));
287     OLSR_DEBUG(LOG_PLUGINS, "New master: %s\n", inet_ntoa(master_ip.v4));
288     if (memcmp(&(guest->master_ip.v4), &(master_ip.v4), sizeof(union olsr_ip_addr)) != 0) {
289       guest->master_ip = master_ip;
290       OLSR_INFO(LOG_PLUGINS, "Updating Routes because %s changed\n", inet_ntoa(guest->ip.v4));
291       update_routes_now();
292     } else {
293       struct ipaddr_str buf1, buf2;
294       OLSR_DEBUG(LOG_PLUGINS, "Not updating, because %s stayed at %s\n",
295           olsr_ip_to_string(&buf1, &guest->ip), olsr_ip_to_string(&buf2, &master_ip));
296     }
297   } else {
298     OLSR_INFO(LOG_PLUGINS, "Updating Routes for unknown client\n");
299     update_routes_now();
300   }
301
302 }
303
304 /**
305  * Initialize plugin
306  * Called after all parameters are passed
307  */
308 int olsrd_plugin_init(void) {
309   list = (struct client_list*) olsr_malloc(sizeof(struct client_list), "client_list");
310
311   OLSR_INFO(LOG_PLUGINS, "OLSRD automated Client Roaming Plugin\n");
312
313   gw_netmask.v4.s_addr = inet_addr("255.255.255.255");
314
315   has_inet_gateway = 0;
316
317   /* create the cookie */
318   event_timer_info1 = olsr_timer_add("cl roam: Event1", &olsr_event1, true);
319   event_timer_info2 = olsr_timer_add("cl roam: Event2", &olsr_event2, true);
320   arping_timer_info = olsr_timer_add("cl roam: Maybe add something", &check_ping_result, true);
321
322   /* Register the GW check */
323   olsr_timer_start(1 * MSEC_PER_SEC, 0, NULL, event_timer_info1);
324   olsr_timer_start(20 * MSEC_PER_SEC, 0, NULL, event_timer_info2);
325
326   /* register functions with olsrd */
327   // somehow my cool new message.....
328   olsr_parser_add_function(&olsr_parser, 134);
329
330   return 1;
331 }
332
333 static void* ping_thread(void* guest) {
334   char ping_command[50];
335   ssize_t result;
336   struct guest_client * target = (struct guest_client *) guest;
337   target->ping_thread_done = 0;
338
339   snprintf(ping_command, sizeof(ping_command), "arping -I ath0 -w 1 -c 1 -q %s", inet_ntoa(target->ip.v4));
340   //printf("%s\n",ping_command);
341   result = system(ping_command);
342   target->ping_thread_done = 1;
343   //printf("ping thread finished\n");
344   return (void*) result;
345 }
346
347 static  __attribute__ ((noreturn)) void* ping_thread_infinite(void * target_void) {
348   char ping_command[50];
349   struct guest_client * target = (struct guest_client*) target_void;
350   while (1) {
351     int ret;
352     snprintf(ping_command, sizeof(ping_command), "arping -I ath0 -q -c 10 %s", inet_ntoa(target->ip.v4));
353     if ((ret = system(ping_command))) {
354       OLSR_WARN(LOG_PLUGINS, "cl_roam: Warning, system '%s' returned %d\n", ping_command, ret);
355     }
356     pthread_testcancel();
357   }
358 }
359
360 static void ping_infinite(struct guest_client * target) {
361   int rc;
362   pthread_t thread;
363   if (target->ping_thread == 0) {
364     rc = pthread_create(&thread, NULL, ping_thread_infinite, (void *) target);
365     if (rc) {
366       printf("ERROR; return code from pthread_create() is %d\n", rc);
367       os_exit(-1);
368     }
369     target->ping_thread = thread;
370     OLSR_INFO(LOG_PLUGINS, "Set up ping-thread for %s\n", inet_ntoa(target->ip.v4));
371   } else
372     OLSR_INFO(LOG_PLUGINS, "Ping-thread for %s already exists!\n", inet_ntoa(target->ip.v4));
373 }
374
375 static void check_ping_result(void *foo) {
376   struct guest_client * host = (struct guest_client *) foo;
377
378   if (!host->ping_thread_done) {
379     OLSR_DEBUG(LOG_PLUGINS, "Ping-thread for %s not finished\n", inet_ntoa(host->ip.v4));
380
381   } else {
382     /* should be same size as (void*) */
383     ssize_t ping_res;
384
385     olsr_timer_stop(host->arping_timer);
386     pthread_join(host->ping_thread_add, (void*) &ping_res);
387     host->arping_timer = NULL;
388     host->ping_thread_done = 0;
389     if (ping_res == 0) {
390       char route_command[50];
391       int ret;
392       OLSR_INFO(LOG_PLUGINS, "Adding Route for %s\n", inet_ntoa(host->ip.v4));
393
394       ip_prefix_list_add(&olsr_cnf->hna_entries, &(host->ip), olsr_netmask_to_prefix(&gw_netmask));
395       host->is_announced = 1;
396       host->remaing_announcements = 15;
397
398       snprintf(route_command, sizeof(route_command), "route add %s dev ath0 metric 0", inet_ntoa(host->ip.v4));
399       if ((ret = system(route_command))) {
400         OLSR_WARN(LOG_PLUGINS, "cl_roam: Warning, system '%s' returned %d\n", route_command, ret);
401       }
402
403       host->master_ip = olsr_cnf->router_id;
404
405       spread_host(host);
406       //This really big time will be overwritten by the next normal hna-announcement
407       single_hna(&host->ip, -1);
408
409       //Append to buffer, will be send at some time. In case it didn't arrive at the old master
410       spread_host(host);
411     } else {
412       host->last_seen += 0.5;
413       check_for_route(host);
414     }
415   }
416 }
417
418 static void check_for_route(struct guest_client * host) {
419   //printf("%f, %i, %x\n",host->last_seen , host->is_announced  ,host->ping_thread_add );
420   if (host->last_seen < 10.0 && !host->is_announced && host->arping_timer == NULL) {
421     int rc;
422
423     //printf("maybe add something\n");
424     if (host->arping_timer_cookie == NULL)
425     //printf("timer started\n");
426     host->arping_timer = olsr_timer_start(250, 5, host, arping_timer_info);
427     rc = pthread_create(&(host->ping_thread_add), NULL, ping_thread, (void *) host);
428   } else if ((host->last_seen > 60.0) && host->is_announced) {
429     char route_command[50];
430     int ret;
431     OLSR_INFO(LOG_PLUGINS, "Removing Route for %s\n", inet_ntoa(host->ip.v4));
432     ip_prefix_list_remove(&olsr_cnf->hna_entries, &host->ip, olsr_netmask_to_prefix(&gw_netmask), olsr_cnf->ip_version);
433     snprintf(route_command, sizeof(route_command), "route del %s dev ath0 metric 0", inet_ntoa(host->ip.v4));
434     if ((ret = system(route_command))) {
435       OLSR_WARN(LOG_PLUGINS, "cl_roam: Warning, system '%s' returned %d\n", route_command, ret);
436     }
437     host->is_announced = 0;
438   } else if (host->is_announced && host->remaing_announcements > 0) {
439     host->remaing_announcements--;
440     spread_host(host);
441     single_hna(&host->ip, -1);
442   }
443 }
444
445 static void check_client_list(struct client_list * clist) {
446   if (clist != NULL && clist->client != NULL) {
447     //ping(clist->client);
448     if (clist->client->is_announced == 1 || clist->client->ping_thread != 0) {
449       if (!check_if_associcated(clist->client)) {
450         if (clist->client->is_announced == 1) {
451           clist->client->last_seen += 5;
452         }
453         if (clist->client->ping_thread != 0) {
454           //printf("attempting to kill ping-thread\n");
455           pthread_detach(clist->client->ping_thread);
456           //pthread_kill(clist->client->ping_thread, 1);
457           //pthread_cancel(clist->client->ping_thread);
458           pthread_cancel(clist->client->ping_thread);
459           //printf("killed ping-thread\n");
460           OLSR_INFO(LOG_PLUGINS, "Killed ping-thread for %s\n", inet_ntoa(clist->client->ip.v4));
461           // clist->client->ping_thread=NULL; (not a pointer !)
462         }
463       }
464     }
465     check_for_route(clist->client);
466     check_client_list(clist->list);
467   }
468 }
469
470 struct guest_client * get_client_by_mac(struct client_list * clist, u_int64_t mac) {
471   if (clist != NULL && clist->client != NULL) {
472     if (clist->client->mac == mac)
473       return clist->client;
474     else
475       return get_client_by_mac(clist->list, mac);
476   } else
477     return NULL;
478 }
479
480 int ip_is_in_guest_list(struct client_list *l, struct guest_client * host) {
481   if (l == NULL)
482     return 0;
483   if (l->client == NULL)
484     return 0;
485   else if (inet_lnaof(l->client->ip.v4) == inet_lnaof(host->ip.v4))
486     return 1;
487   else
488     return ip_is_in_guest_list(l->list, host);
489 }
490
491 void check_local_leases(struct client_list * clist) {
492   check_leases(clist, "/var/dhcp.leases", 1.0);
493 }
494
495 void check_leases(struct client_list * clist, const char *file, float def_last_seen) {
496   char s1[50];
497   char s3[50];
498   long long int one, two, three, four, five, six;
499
500   FILE * fp = fopen(file, "r");
501   if (fp == NULL) {
502     printf("failed to open %s\n", file);
503   }
504
505   while (1) {
506     int parse = fscanf(fp, "%s %llx:%llx:%llx:%llx:%llx:%llx %s %*s %*s\n", s1, &one, &two, &three, &four, &five, &six,
507         s3);
508     if (parse == EOF)
509       break;
510     if (parse == 8) {
511       struct guest_client* user;
512       //printf ("String 3 = %s\n", s3);
513       user = (struct guest_client*) malloc(sizeof(struct guest_client));
514       inet_aton(s3, &(user->ip.v4));
515       user->mac = six | five << 8 | four << 16 | three << 24 | two << 32 | one << 40;
516       user->last_seen = def_last_seen;
517       user->is_announced = 0;
518       user->ping_thread = 0;
519       user->arping_timer = NULL;
520       user->arping_timer_cookie = NULL;
521       //printf("last seen on Add %f\n",user->last_seen);
522       add_client_to_list(clist, user);
523     }
524   }
525   fclose(fp);
526 }
527
528 static void check_remote_leases(struct client_list * clist) {
529   FILE *my_leases;
530   FILE *fp;
531   char s1[50];
532   char s3[50];
533   long long int one, two, three, four, five, six;
534
535   fp = fopen("/tmp/otherclient", "r");
536   if (fp == NULL) {
537     printf("failed to open %s\n", "/tmp/otherclient");
538   }
539   my_leases = fopen("/var/dhcp.leases", "a");
540   if (my_leases == NULL) {
541     printf("failed to open %s\n", "/var/dhcp.leases");
542   }
543
544   while (1) {
545     int parse = fscanf(fp, "%s %llx:%llx:%llx:%llx:%llx:%llx %s %*s %*s\n", s1, &one, &two, &three, &four, &five, &six,
546         s3);
547     if (parse == EOF)
548       break;
549     if (parse == 8) {
550       struct guest_client* user;
551       //printf ("String 3 = %s\n", s3);
552       user = (struct guest_client*) malloc(sizeof(struct guest_client));
553       inet_aton(s3, &(user->ip.v4));
554       user->mac = six | five << 8 | four << 16 | three << 24 | two << 32 | one << 40;
555       user->last_seen = 30.0;
556       user->is_announced = 0;
557       user->ping_thread = 0;
558       user->arping_timer = NULL;
559       user->arping_timer_cookie = NULL;
560       //printf("last seen on Add %f\n",user->last_seen);
561
562       if (!(ip_is_in_guest_list(clist, user))) {
563         fprintf(my_leases, "%s %llx:%llx:%llx:%llx:%llx:%llx %s * *\n", s1, one, two, three, four, five, six, s3);
564       }
565       add_client_to_list(clist, user);
566     }
567   }
568   fclose(fp);
569   fclose(my_leases);
570 }
571
572 static int check_if_associcated(struct guest_client *client) {
573   char s2[50];
574   float last_rx;
575   int parse;
576   uint64_t mac;
577   long long int one, two, three, four, five, six;
578
579   FILE * fp = fopen("/proc/net/madwifi/ath0/associated_sta", "r");
580   if (fp == NULL) {
581     printf("failed to open %s\n", "/proc/net/madwifi/ath0/associated_sta");
582     return EXIT_FAILURE;
583   }
584   //FILE * fp = fopen("/home/raphael/tmp/leases", "r");
585
586   while (1) {
587     parse = fscanf(fp, "macaddr: <%llx:%llx:%llx:%llx:%llx:%llx>\n", &one, &two, &three, &four, &five, &six);
588     if (parse == EOF || parse != 6)
589       break;
590     mac = six | five << 8 | four << 16 | three << 24 | two << 32 | one << 40;
591     //printf ("am at %llx\n", mac);
592     if (mac == client->mac) {
593       //printf("found it!\n");
594       fclose(fp);
595       return 1;
596     }
597     parse = fscanf(fp, " rssi %s\n", s2);
598     if (parse == EOF)
599       break;
600     parse = fscanf(fp, " last_rx %f\n", &last_rx);
601     if (parse == EOF)
602       break;
603   }
604
605   fclose(fp);
606
607   return 0;
608 }
609
610 static void check_associations(struct client_list * clist) {
611   char s2[50];
612   float last_rx;
613   int parse;
614
615   long long int one, two, three, four, five, six;
616   FILE * fp = fopen("/proc/net/madwifi/ath0/associated_sta", "r");
617   if (fp == NULL) {
618     printf("failed to open %s\n", "/proc/net/madwifi/ath0/associated_sta");
619   }
620   //FILE * fp = fopen("/home/raphael/tmp/leases", "r");
621
622   while (1) {
623     uint64_t mac;
624     struct guest_client* node;
625     parse = fscanf(fp, "macaddr: <%llx:%llx:%llx:%llx:%llx:%llx>\n", &one, &two, &three, &four, &five, &six);
626     if (parse == EOF || parse != 6)
627       break;
628     mac = six | five << 8 | four << 16 | three << 24 | two << 32 | one << 40;
629     //printf ("macaddr: %llx\n", mac);
630     parse = fscanf(fp, " rssi %s\n", s2);
631     if (parse == EOF)
632       break;
633     //printf ("rssi = %s\n", s2);
634     parse = fscanf(fp, " last_rx %f\n", &last_rx);
635     if (parse == EOF)
636       break;
637     //printf ("last_rx = %f\n", last_rx);
638     node = get_client_by_mac(clist, mac);
639     if (node != NULL) {
640       //printf("Sichtung!\n");
641       node->last_seen = last_rx;
642       if (node->ping_thread == 0) {
643         ping_infinite(node);
644       }
645     }
646   }
647   fclose(fp);
648 }
649
650 void add_client_to_list(struct client_list * clist, struct guest_client * host) {
651   if (ip_is_in_guest_list(clist, host)) {
652     free(host);
653   } else {
654     if (clist->client != NULL) {
655       struct client_list * this_one;
656       this_one = (struct client_list *) olsr_malloc(sizeof(struct client_list), "clist");
657       this_one->client = host;
658       this_one->list = clist->list;
659       clist->list = this_one;
660       OLSR_INFO(LOG_PLUGINS, "Keeping track of %s\n", inet_ntoa(host->ip.v4));
661     } else {
662       clist->client = host;
663       OLSR_INFO(LOG_PLUGINS, "Keeping track of %s\n", inet_ntoa(host->ip.v4));
664     }
665     ping_infinite(host);
666     host->arping_timer = NULL;
667     check_for_route(host);
668
669   }
670 }
671
672 static void check_for_new_clients(struct client_list * clist) {
673   check_local_leases(clist);
674   check_associations(clist);
675 }
676
677 static void* check_neighbour_host(void* neighbour) {
678   struct nbr_entry *nbr = (struct nbr_entry*) neighbour;
679   union olsr_ip_addr foobar = nbr->nbr_addr;
680
681   char wget_command[70];
682
683   snprintf(wget_command, sizeof(wget_command), "wget -T 2 -q -O /tmp/otherclient http://%s/dhcp.leases", inet_ntoa(
684       foobar.v4));
685   if (system(wget_command) == 0) {
686
687     check_remote_leases(list);
688   }
689   return NULL;
690 }
691
692 static void spread_host(struct guest_client * host) {
693   struct interface *ifp, *iterator;
694   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE] __attribute__ ((aligned));
695   uint8_t *curr = msg_buffer;
696   uint8_t *length_field, *last;
697
698   OLSR_INFO(LOG_PACKET_CREATION, "Building HNA\n-------------------\n");
699
700   // My message Type 134:
701   pkt_put_u8(&curr, 134);
702   // hna-validity
703   pkt_put_reltime(&curr, 20000);
704
705   length_field = curr;
706   pkt_put_u16(&curr, 0); /* put in real messagesize later */
707
708   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
709
710   // TTL
711   pkt_put_u8(&curr, 3);
712   pkt_put_u8(&curr, 0);
713   pkt_put_u16(&curr, get_msg_seqno());
714
715   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize;
716
717   // Actual message
718   //first IP to announce
719   pkt_put_ipaddress(&curr, &(host->ip));
720   // second: announcing IP
721   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
722
723   //Put in Message size
724   pkt_put_u16(&length_field, curr - msg_buffer);
725
726   OLSR_FOR_ALL_INTERFACES(ifp, iterator) {
727     if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
728       net_output(ifp);
729       set_buffer_timer(ifp);
730     }
731     // buffer gets pushed out in single_hna, or at flush-time
732     net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
733   }
734
735 }
736
737 // sends packet immedeately!
738 void single_hna(union olsr_ip_addr * ip, uint32_t vtime) {
739   union olsr_ip_addr subnet;
740   struct interface *ifp, *iterator;
741   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE] __attribute__ ((aligned));
742   uint8_t *curr = msg_buffer;
743   uint8_t *length_field, *last;
744
745   //printf("single hna %x with time %i\n",*ip, time);
746   OLSR_INFO(LOG_PACKET_CREATION, "Building HNA\n-------------------\n");
747
748   // My message Type 134:
749   pkt_put_u8(&curr, HNA_MESSAGE);
750   // hna-validity
751   pkt_put_reltime(&curr, vtime);
752
753   length_field = curr;
754   pkt_put_u16(&curr, 0); /* put in real messagesize later */
755
756   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
757
758   // TTL
759   pkt_put_u8(&curr, 2);
760   pkt_put_u8(&curr, 0);
761   pkt_put_u16(&curr, get_msg_seqno());
762
763   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize;
764
765   inet_aton("255.255.255.255", &subnet.v4);
766   pkt_put_ipaddress(&curr, ip);
767   pkt_put_ipaddress(&curr, &subnet);
768
769   pkt_put_u16(&length_field, curr - msg_buffer);
770
771   OLSR_FOR_ALL_INTERFACES(ifp, iterator) {
772     net_output(ifp);
773     net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
774     net_output(ifp);
775     set_buffer_timer(ifp);
776   }
777 }
778
779 static void olsr_event1(void *foo __attribute__ ((unused)) ) {
780   check_for_new_clients(list);
781   check_client_list(list);
782 }
783
784 static void olsr_event2(void *foo  __attribute__ ((unused))) {
785   struct nbr_entry *nbr, *iterator;
786
787   OLSR_FOR_ALL_NBR_ENTRIES(nbr, iterator) {
788     int rc;
789     pthread_t thread;
790     rc = pthread_create(&thread, NULL, check_neighbour_host, (void *) nbr);
791     if (rc) {
792       printf("ERROR; return code from pthread_create() is %d\n", rc);
793       os_exit(-1);
794     }
795   }
796 }
797