aa934066ebc2bb23f3e349c4ebc523a22e7c15cd
[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_cookie;
79 static union olsr_ip_addr gw_netmask;
80
81 /**
82  * Plugin interface version
83  * Used by main olsrd to check plugin interface version
84  */
85 int
86 olsrd_plugin_interface_version(void)
87 {
88   return PLUGIN_INTERFACE_VERSION;
89 }
90
91 static const struct olsrd_plugin_parameters plugin_parameters[] = {
92 };
93
94
95
96 typedef struct { 
97         struct in_addr ip;
98         u_int64_t mac;
99         struct in_addr from_node;
100         char is_announced;
101         float last_seen;
102  } guest_client;
103
104
105
106 typedef struct {
107         guest_client *client;
108         struct client_list *list;
109 } client_list;
110
111
112
113
114 client_list *list;
115 struct interface *ifn;
116
117
118
119 void ping(guest_client *);
120
121 void
122 olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
123 {
124   *params = plugin_parameters;
125   *size = ARRAYSIZE(plugin_parameters);
126 }
127
128
129
130 void *PrintHello(void *threadid)
131 {
132    long tid;
133    tid = (long)threadid;
134    printf("Hello World! It's me, thread #%ld!\n", tid);
135    pthread_exit(NULL);
136 }
137
138
139
140
141
142 /**
143  * Initialize plugin
144  * Called after all parameters are passed
145  */
146 int
147 olsrd_plugin_init(void)
148 {
149
150
151   
152   list=(client_list*)malloc( sizeof(client_list) );
153
154
155
156   OLSR_INFO(LOG_PLUGINS, "OLSRD automated Client Roaming Plugin\n");
157
158
159   gw_netmask.v4.s_addr = inet_addr("255.255.255.255");
160
161   has_inet_gateway = 0;
162
163
164   /* create the cookie */
165   event_timer_cookie = olsr_alloc_cookie("cl roam: Event", OLSR_COOKIE_TYPE_TIMER);
166
167   /* Register the GW check */
168   olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, &olsr_event, NULL, event_timer_cookie);
169   //system("echo \"1\" ");
170   //pthread_create(&ping_thread, NULL, &do_ping, NULL);
171   //system("echo \"2\" ");
172   //CreateThread(NULL, 0, do_ping, NULL, 0, &ThreadId);
173   //if (pthread_create(&ping_thread, NULL, do_ping, NULL) != 0) {
174    // OLSR_WARN(LOG_PLUGINS, "pthread_create() error");
175    // return 0;
176   //}
177
178
179
180
181
182
183
184   return 1;
185 }
186
187
188
189 int ping_thread(guest_client * target)
190 {
191
192     char ping_command[50];
193
194
195     snprintf(ping_command, sizeof(ping_command), "arping -I ath0 -w 1 -c 1 -q %s", inet_ntoa(target->ip));
196     return system(ping_command);
197
198 }
199
200
201
202 void ping_thread_infinite(guest_client * target)
203 {
204     char ping_command[50];
205
206
207     snprintf(ping_command, sizeof(ping_command), "arping -I ath0 -q %s", inet_ntoa(target->ip));
208     system(ping_command);
209
210 }
211
212
213
214 void ping(guest_client * target)
215 {
216         int rc;
217         pthread_t thread;
218     rc = pthread_create(&thread, NULL, ping_thread, (void *) target   );
219     if (rc){
220        printf("ERROR; return code from pthread_create() is %d\n", rc);
221        exit(-1);
222     }
223 }
224
225 void ping_infinite(guest_client * target)
226 {
227         int rc;
228         pthread_t thread;
229     rc = pthread_create(&thread, NULL, ping_thread_infinite, (void *) target   );
230     if (rc){
231        printf("ERROR; return code from pthread_create() is %d\n", rc);
232        exit(-1);
233     }
234 }
235
236
237
238
239
240
241
242
243 struct olsr_message msg;
244
245
246
247 void add_route(void* guest) {
248
249         guest_client * host = (guest_client *) guest;
250
251         if (ping_thread(host)==0) {
252
253                 OLSR_DEBUG(LOG_PLUGINS, "Adding Route\n");
254                 printf("Added Route\n");
255                 ip_prefix_list_add(&olsr_cnf->hna_entries, &(host->ip), olsr_netmask_to_prefix(&gw_netmask));
256                 host->is_announced=1;
257         } else
258                   printf("Decided not to\n");
259 }
260
261
262
263
264
265 void check_for_route(guest_client * host)
266 {
267
268   if (host->last_seen < 5.0 && ! host->is_announced) {
269           pthread_t add;
270           printf("maybe add something\n");
271           int rc = pthread_create(&add, NULL, add_route, (void *)host);
272           if (rc){
273                    printf("ERROR; return code from pthread_create() is %d\n", rc);
274                    exit(-1);
275                 }
276   } else if ((host->last_seen > 5.0) &&  host->is_announced) {
277       OLSR_DEBUG(LOG_PLUGINS, "Removing Route\n");
278       system("echo \"Entferne route\" ");
279       ip_prefix_list_remove(&olsr_cnf->hna_entries, &(host->ip), olsr_netmask_to_prefix(&gw_netmask), olsr_cnf->ip_version);
280       host->is_announced=0;
281 }
282 }
283
284 void check_client_list(client_list * clist) {
285   if (clist!=NULL && clist->client!=NULL) {
286
287     //ping(clist->client);
288         if( ! check_if_associcated(clist->client))
289                 clist->client->last_seen+=2;
290     check_for_route(clist->client);
291
292
293     check_client_list(clist->list);
294   }
295 }
296
297
298
299 guest_client * get_client_by_mac(client_list * clist, u_int64_t mac) {
300   if (clist!=NULL && clist->client!=NULL) {
301
302     if (clist->client->mac == mac)
303         return clist->client;
304     else
305         return get_client_by_mac(clist->list, mac);
306   }
307   else
308           return NULL;
309 }
310
311
312
313 int ip_is_in_guest_list(client_list * list, guest_client * host) {
314 if (list==NULL)
315   return 0;
316 if (list->client==NULL)
317   return 0;
318 else if (inet_lnaof(list->client->ip) == inet_lnaof(host->ip))
319   return 1;
320 else
321   return ip_is_in_guest_list(list->list, host);
322 }
323
324
325 void check_local_leases(client_list * clist){
326   check_leases(clist,"/var/dhcp.leases" , 1.0);
327 }
328
329
330 void check_leases(client_list * clist, char file[], float def_last_seen) {
331           FILE * fp = fopen(file, "r");
332           char s1[50];
333           char s2[50];
334           char s3[50];
335           char s4[50];
336           long long int one, two, three, four, five, six;
337
338           while (1) {
339                   int parse = fscanf (fp, "%s %llx:%llx:%llx:%llx:%llx:%llx %s %s", s1, &one, &two, &three, &four, &five, &six, s3, s4);
340             if (parse==EOF)
341               break;
342             if(parse==9) {
343             guest_client* user;
344             //printf ("String 3 = %s\n", s3);
345             user = (guest_client*)malloc( sizeof(guest_client) );
346             inet_aton(s3, &(user->ip));
347             user->mac= six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40;
348             user->last_seen=def_last_seen;
349             user->is_announced=0;
350             //printf("last seen on Add %f\n",user->last_seen);
351             add_client_to_list(clist, user);
352
353         }
354           }
355           fclose(fp);
356
357
358         }
359
360
361
362
363 void check_remote_leases(client_list * clist){
364   check_leases(clist,"/tmp/otherclient" , 20.0);
365
366 }
367
368
369
370
371
372 int check_if_associcated(guest_client *client)
373 {
374   FILE * fp = fopen("/proc/net/madwifi/ath0/associated_sta", "r");
375   //FILE * fp = fopen("/home/raphael/tmp/leases", "r");
376   char s1[50];
377   char s2[50];
378   char s3[50];
379   int rssi;
380   float last_rx;
381   int parse;
382
383   long long int one, two, three, four, five, six;
384
385   while (1) {
386     parse = fscanf (fp, "macaddr: <%llx:%llx:%llx:%llx:%llx:%llx>\n", &one, &two, &three, &four, &five, &six);
387     if (parse==EOF || parse!=6)
388       break;
389     if ((six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40)==client->mac) {
390         fclose(fp);
391         return 1;
392     }
393     if (parse==EOF)
394           break;
395     //printf ("rssi = %s\n", s2);
396     parse = fscanf (fp, " last_rx %f\n", &last_rx);
397     if (parse==EOF)
398           break;
399
400   }
401   fclose(fp);
402
403
404 }
405
406
407
408
409
410
411
412
413 // Will be handy to identify when a client roamed to us. Not used yet.
414 void check_associations(client_list * clist){
415   FILE * fp = fopen("/proc/net/madwifi/ath0/associated_sta", "r");
416   //FILE * fp = fopen("/home/raphael/tmp/leases", "r");
417   char s1[50];
418   char s2[50];
419   char s3[50];
420   int rssi;
421   float last_rx;
422   int parse;
423
424   long long int one, two, three, four, five, six;
425
426   while (1) {
427     parse = fscanf (fp, "macaddr: <%llx:%llx:%llx:%llx:%llx:%llx>\n", &one, &two, &three, &four, &five, &six);
428     if (parse==EOF || parse!=6)
429       break;
430     uint64_t mac = six | five<<8 | four<<16 | three<<24 | two<<32 | one<<40;
431     //printf ("macaddr: %llx\n", mac);
432     parse = fscanf (fp, " rssi %s\n", s2);
433     if (parse==EOF)
434           break;
435     //printf ("rssi = %s\n", s2);
436     parse = fscanf (fp, " last_rx %f\n", &last_rx);
437     if (parse==EOF)
438           break;
439     //printf ("last_rx = %f\n", last_rx);
440     guest_client* node = get_client_by_mac(clist, mac);
441     if (node!=NULL) {
442         //printf("Sichtung!\n");
443         node->last_seen=last_rx;
444         //printf("last_seen= %f\n",node->last_seen);
445     }
446
447   }
448   fclose(fp);
449
450
451 }
452
453
454
455
456
457 void add_client_to_list(client_list * clist, guest_client * host) {
458   if (ip_is_in_guest_list(clist,  host)) {
459     free(host);
460   }
461   else {
462     if (clist->client!=NULL) {
463       client_list * this_one;
464       this_one = (client_list *)malloc( sizeof(client_list) );
465       this_one->client = host;
466       this_one->list=clist->list;
467       clist->list=this_one;
468       printf("added something\n");
469     } else {
470       clist->client=host;
471       printf("added something\n");
472     }
473     ping_infinite(host);
474   }
475 }
476
477
478
479
480
481 void check_for_new_clients(client_list * clist) {
482     check_local_leases(clist);
483     check_associations(clist);
484 }
485
486
487
488
489
490 void
491 olsr_event(void *foo __attribute__ ((unused)))
492 {
493         struct nbr_entry *nbr;
494         check_for_new_clients(list);
495     check_client_list(list);
496
497
498
499
500
501     OLSR_FOR_ALL_NBR_ENTRIES(nbr) {
502         union olsr_ip_addr foobar = nbr->nbr_addr;
503
504                 char wget_command[70];
505
506
507                 snprintf(wget_command, sizeof(wget_command), "wget -q -O /tmp/otherclient http://%s/dhcp.leases", inet_ntoa(foobar.v4));
508
509                 system(wget_command);
510
511                 check_remote_leases(list);
512
513         }OLSR_FOR_ALL_NBR_ENTRIES_END();
514
515
516
517
518
519
520
521
522
523 }
524
525
526
527
528
529
530