00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include <sys/types.h>
00078 #include <sys/socket.h>
00079 #include <sys/ioctl.h>
00080 #include <sys/time.h>
00081 #include <netinet/ip_icmp.h>
00082 #include <netinet/in.h>
00083 #include <arpa/inet.h>
00084 #include <asm/types.h>
00085 #include <stdio.h>
00086 #include <stddef.h>
00087 #include <errno.h>
00088 #include <fcntl.h>
00089 #include <ctype.h>
00090 #include <stdlib.h>
00091 #include <string.h>
00092 #include <unistd.h>
00093 #include <syslog.h>
00094 #include <assert.h>
00095
00096 #include <unistd.h>
00097 #include <features.h>
00098 #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
00099 #include <netpacket/packet.h>
00100 #include <net/ethernet.h>
00101 #include <netinet/if_ether.h>
00102 #else
00103 #include <linux/if_packet.h>
00104 #include <linux/if_ether.h>
00105 #endif
00106 #include "owntypes.h"
00107 #include <linux/filter.h>
00108
00109 #include "mn.h"
00110 #include "monitor.h"
00111 #include "debug.h"
00112 #include "util.h"
00113 #include "mn_agentadv.h"
00114 #include "mn_handler.h"
00115 #include "list.h"
00116 #include "dyn_wireless.h"
00117 #include "dyn_iwspy_rec.h"
00118
00119 #ifndef TRUE
00120 #define TRUE 1
00121 #endif
00122
00123 #ifndef FALSE
00124 #define FALSE 0
00125 #endif
00126
00127 #define DEBUG_FLAG 'm'
00128 #define REC_DUMP_TYPE 4
00129
00130
00132
00133
00134
00135 static int monitor_interface_up(void *data);
00136 static int monitor_interface_down(void *data);
00137
00138 static int monitor_get_fa(void *data);
00139 static int monitor_add_fa(void *data);
00140 static int monitor_del_fa(void *data);
00141
00144 struct monitor_global_data mon_conf;
00145 struct monitor_interface mon_devs[MAX_INTERFACES];
00146 int mon_rec_qual_initialized;
00147
00148
00150
00151
00152
00153
00154
00155 struct monitor_conf_vars monitor_conf[] = {
00156 {"Threshold (0-100) ", 1, &mon_conf.threshold, 0, 100},
00157 {"Min-balance (0-100) ", 1, &mon_conf.min_balance, 0, 100},
00158 {"Expirepercent (1-300) ", 1, &mon_conf.expiretime, 1, 300},
00159 {"Old-FA-factor (0-100) ", 1, &mon_conf.old_fa_factor, 0, 100},
00160 {"Worst-min-time (0- ) ", 8, &mon_conf.worst_min_time, 0, -1},
00161 {"Worst-max-time (0- ) ", 8, &mon_conf.worst_max_time, 0, -1},
00162 {"Average-length (1-10) ", 1, &mon_conf.average_length, 1, 10},
00163 {"Default-channel (1-14) ", 1, &mon_conf.default_ch, 1, 14},
00164 {"Record-quality (0, 1) ", 1, &mon_conf.rec_qual, 0, 1},
00165 {"SQ-cache (0, 1) ", 1, &mon_conf.SQ_cache, 0, 1},
00166 {"", 0, NULL, 0, 0}
00167 };
00168
00169
00170
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 static void update_statistics(struct sockaddr *hwa, struct iw_quality *qual,
00182 struct timeval tstamp,
00183 struct monitor_interface *dev, int monitored)
00184 {
00185 unsigned int j, k, i = 0, sum, p;
00186
00187
00188 for (i = 0; i < monitored; i++) {
00189
00190 if (!(qual[i].updated & 0x7))
00191 continue;
00192
00193 for (j = 0; j < MAX_MONITOR; j++) {
00194 if (dev->mon[j].active != 1 ||
00195 (memcmp(hwa[i].sa_data,
00196 dev->mon[j].adv->adv.from.sll_addr,
00197 ETH_ALEN)))
00198 continue;
00199
00200
00201 p = next(dev->mon[j].q10_index);
00202 dev->mon[j].q10_index = p;
00203
00204 dev->mon[j].qual.level = qual[i].level;
00205 dev->mon[j].qual.qual = qual[i].qual;
00206 dev->mon[j].qual.noise = qual[i].noise;
00207 dev->mon[j].qual.updated = qual[i].updated;
00208
00209
00210
00211 if (dev->mon[j].qual.qual > dev->range.max_qual.qual)
00212 dev->mon[j].q10[p] =
00213 dev->mon[j].q10[prev(p)];
00214 else
00215 dev->mon[j].q10[p] =
00216 dev->mon[j].qual.qual;
00217
00218
00219 dev->mon[j].updated.tv_sec = tstamp.tv_sec;
00220 dev->mon[j].updated.tv_usec = tstamp.tv_usec;
00221
00222 if (monitor_check_policy(EAGER_SWITCH_BIT)) {
00223 dev->mon[j].avg = ((100*dev->mon[j].q10[p])/
00224 dev->range.max_qual.qual);
00225 return;
00226 }
00227
00228
00229
00230
00231
00232
00233 if (mon_conf.average_length <= 0 ||
00234 mon_conf.average_length > 10) {
00235 DEBUG(DEBUG_FLAG, "update_statistics: "
00236 "configuration variable: "
00237 "average_length was out of range! "
00238 " (%d)\n", mon_conf.average_length);
00239 mon_conf.average_length = DEFAULT_AVG_LEN;
00240 }
00241
00242 sum = dev->mon[j].q10[p];
00243 for (k = 1; k < mon_conf.average_length; k++) {
00244
00245 if (dev->mon[j].q10[prev(p)] >= 255) {
00246 dev->mon[j].q10[prev(p)] =
00247 dev->mon[j].q10[p];
00248 }
00249 sum += dev->mon[j].q10[prev(p)];
00250 p = prev(p);
00251 }
00252
00253
00254 dev->mon[j].avg = (unsigned short)
00255 ((sum*100/mon_conf.average_length)/
00256 dev->range.max_qual.qual);
00257 }
00258 }
00259 }
00260
00261 static int get_qual_avg(struct monitor_interface *dev, unsigned char *hw)
00262 {
00263 int j;
00264
00265 for (j = 0; j < MAX_MONITOR; j++) {
00266 if (dev->mon[j].active != 1 ||
00267 (memcmp(hw, dev->mon[j].adv->adv.from.sll_addr, ETH_ALEN)))
00268 continue;
00269
00270 return dev->mon[j].avg;
00271 }
00272
00273 DEBUG(DEBUG_FLAG, "get_qual_avg: mac not found!\n");
00274 return -1;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 static int monitor(struct monitor_interface *dev, struct agentadv_data *adv,
00292 struct timeval tstamp)
00293 {
00294 int i, ph = -1, monitored, ret;
00295 struct sockaddr *hw;
00296 struct iw_quality *qual;
00297 char buffer[(sizeof(struct iw_quality) +
00298 sizeof(struct sockaddr)) * (IW_MAX_SPY)];
00299
00300
00301 monitored = dyn_wireless_iwspy_get(dev->sock, dev->ifname, buffer);
00302 if (monitored == -1) {
00303 DEBUG(DEBUG_FLAG,"monitor: get monitored addresses failed\n");
00304 return -1;
00305 }
00306 hw = (struct sockaddr *)buffer;
00307 qual = (struct iw_quality *)
00308 (buffer + (sizeof(struct sockaddr) * monitored));
00309
00310
00311
00312 for (i = 0; i < MAX_MONITOR; i++) {
00313 if (dev->mon[i].active == 0)
00314 continue;
00315 if (adv->addr.s_addr == dev->mon[i].adv->addr.s_addr ||
00316 !memcmp(adv->adv.from.sll_addr,
00317 dev->mon[i].adv->adv.from.sll_addr, ETH_ALEN)) {
00318 DEBUG(DEBUG_FLAG, "monitor: already monitoring %s\n",
00319 inet_ntoa(dev->mon[i].adv->addr));
00320 update_statistics(hw, qual, tstamp, dev, monitored);
00321 return -3;
00322 }
00323 }
00324
00325
00326
00327
00328 ph = get_free_slot(&tstamp, dev);
00329 if (ph < 0) {
00330 DEBUG(DEBUG_FLAG, "monitor: worst entry was current fa\n");
00331 return -2;
00332 }
00333
00334
00335 memset(&dev->mon[ph], 0, sizeof(struct monitor_address));
00336 memset(dev->mon[ph].q10, MAXINT, sizeof(dev->mon[ph].q10));
00337 assert(adv != NULL);
00338 if (dev->mon[ph].adv != NULL)
00339 dev->mon[ph].adv->mon = NULL;
00340 dev->mon[ph].adv = adv;
00341 dev->mon[ph].adv->mon = &dev->mon[ph];
00342 dev->mon[ph].added.tv_sec = tstamp.tv_sec;
00343 dev->mon[ph].added.tv_usec = tstamp.tv_usec;
00344 dev->mon[ph].active = 1;
00345 update_statistics(hw, qual, tstamp, dev, monitored);
00346
00347 if (mon_conf.SQ_cache) {
00348 if (dev->spy_number < MAX_MONITOR)
00349 dev->spy_number++;
00350 return ph;
00351 }
00352
00353
00354
00355 if (monitored < MAX_KERNEL) {
00356 memcpy((char *)hw[monitored].sa_data,
00357 (char *)adv->adv.from.sll_addr, ETH_ALEN);
00358 monitored++;
00359 } else {
00360
00361 for (i = 0; i < monitored; i++) {
00362 if (dev != NULL && dev->mon[ph].adv != NULL &&
00363 memcmp((char *)hw[i].sa_data,
00364 (char *)dev->mon[ph].adv->adv.from.sll_addr,
00365 ETH_ALEN) == 0) {
00366
00367 DEBUG(DEBUG_FLAG, "monitor: Replace "
00368 "worst entry buffer\n");
00369 memcpy((char *)hw[i].sa_data,
00370 (char *)adv->adv.from.sll_addr,
00371 ETH_ALEN);
00372 break;
00373 }
00374 }
00375 }
00376
00377 ret = dyn_wireless_iwspy_set(dev->sock, dev->ifname,
00378 buffer, monitored);
00379 if (ret == -1) {
00380 DEBUG(DEBUG_FLAG, "Call to dyn_wireless_iwspy_set failed\n");
00381 return -1;
00382 }
00383 if (dev->spy_number < MAX_MONITOR)
00384 dev->spy_number++;
00385
00386 return ph;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 static int demonitor(struct monitor_interface *dev, struct in_addr addr)
00403 {
00404 int monitored, i, j, found = -1, ret;
00405 struct sockaddr *hw_set, *hw_get;
00406 char buffer_get[(sizeof(struct iw_quality) +
00407 sizeof(struct sockaddr)) * (IW_MAX_SPY)];
00408 char buffer_set[(sizeof(struct iw_quality) +
00409 sizeof(struct sockaddr)) * (IW_MAX_SPY)];
00410
00411
00412 for (i = 0; i < MAX_MONITOR; i++) {
00413 if (dev->mon[i].active == 0)
00414 continue;
00415 assert(dev->mon[i].adv != NULL);
00416 if (dev->mon[i].adv->addr.s_addr == addr.s_addr) {
00417 dev->mon[i].active = 0;
00418 dev->mon[i].adv->mon = NULL;
00419 found = i;
00420 break;
00421 }
00422 }
00423
00424 if (found == -1) {
00425 DEBUG(DEBUG_FLAG,
00426 "monitor_del_fa: Entry not found! (%s)\n",
00427 dev->ifname);
00428 return -2;
00429 }
00430
00431 #ifndef IWSPY_SIM
00432
00433 monitored = dyn_wireless_iwspy_get(dev->sock, dev->ifname, buffer_get);
00434 hw_get = (struct sockaddr *)buffer_get;
00435 hw_set = (struct sockaddr *)buffer_set;
00436
00437
00438 DEBUG(DEBUG_FLAG, "monitor_del_fa: Remove entry from the "
00439 "buffer (%d/%d)\n", found, monitored);
00440 assert(dev->mon[found].adv != NULL);
00441 for (i = 0, j = 0; i < monitored; i++) {
00442 if ((memcmp((unsigned char *)(hw_get[i].sa_data),
00443 (unsigned char *)
00444 (dev->mon[found].adv->adv.from.sll_addr),
00445 ETH_ALEN)) != 0) {
00446 memcpy((char *)(hw_set[j].sa_data),
00447 (char *)(hw_get[i].sa_data),
00448 ETH_ALEN);
00449 j++;
00450 }
00451 }
00452
00453
00454 ret = dyn_wireless_iwspy_set(dev->sock, dev->ifname, buffer_set, j);
00455 if (ret) {
00456 DEBUG(DEBUG_FLAG, "dyn_wireless_iwspy_set failed (%s)\n",
00457 dev->ifname);
00458 return -1;
00459 }
00460 #endif
00461
00462 return 0;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 static int monitor_del_fa(void *data)
00476 {
00477 struct agentadv_data *adv = NULL;
00478 struct monitor_interface *dev;
00479
00480 if (data) {
00481 adv = ((struct event_FA *)data)->adv;
00482 }
00483
00484 if (adv == NULL)
00485 return -1;
00486
00487 DEBUG(DEBUG_FLAG, "monitor_del_fa: %s\n",
00488 inet_ntoa(adv->addr));
00489
00490
00491 dev = monitor_get_dev(adv->ifname);
00492 if (!dev || !dev->iwspy_support) {
00493 DEBUG(DEBUG_FLAG, "monitor_del_fa: Not a wireless "
00494 "interface (%s)\n", adv->ifname);
00495 return 1;
00496 }
00497
00498 return demonitor(dev, adv->addr);
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508 static void mark_new_entries(void)
00509 {
00510 int i, j;
00511 struct timeval timest;
00512 int lifetime = 0;
00513
00514 gettimeofday(×t,NULL);
00515
00516
00517 for (j = 0; j < MAX_INTERFACES; j++) {
00518 if (!mon_devs[j].in_use || !mon_devs[j].iwspy_support)
00519 continue;
00520
00521
00522 for (i = 0; i < MAX_MONITOR; i++) {
00523 if (mon_devs[j].mon[i].active != 1) {
00524 mon_devs[j].vector_update[i] = 0;
00525 continue;
00526 }
00527
00528
00529
00530 if (!monitor_check_policy(EARLY_EXPIRE_BIT)) {
00531
00532 mon_devs[j].vector_update[i] = 1;
00533 } else {
00534
00535
00536
00537
00538
00539
00540 lifetime = (int)
00541 (mon_devs[j].mon[i].adv->expire.tv_sec -
00542 mon_devs[j].mon[i].adv->last.tv_sec);
00543 if ((mon_devs[j].mon[i].updated.tv_sec +
00544 ((lifetime*mon_conf.expiretime)/100))
00545 > timest.tv_sec) {
00546 mon_devs[j].vector_update[i] = 1;
00547 mon_devs[j].mon[i].active = 1;
00548 } else {
00549 DEBUG(DEBUG_FLAG, "mark_new_entries: "
00550 "inactive (old) entry\n");
00551 mon_devs[j].vector_update[i] = 0;
00552
00553 mon_devs[j].mon[i].adv->priority = 1;
00554 }
00555 }
00556
00557
00558 if (*mon_conf.current_adv != NULL &&
00559 !strncmp((*mon_conf.current_adv)->ifname,
00560 mon_devs[j].ifname, IFNAMSIZ) &&
00561 (*mon_conf.current_adv)->addr.s_addr ==
00562 mon_devs[j].mon[i].adv->addr.s_addr) {
00563 mon_conf.current_fa = i;
00564 memcpy(mon_conf.current_dev,
00565 mon_devs[j].ifname, IFNAMSIZ);
00566 DEBUG(DEBUG_FLAG, "mark_new_entries: "
00567 "curr.dev %s, curr.fa %d\n",
00568 mon_conf.current_dev,
00569 mon_conf.current_fa);
00570 }
00571
00572
00573
00574
00575 }
00576 }
00577
00578 return;
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 static int test_newest_fa(struct agentadv_data *adv)
00591 {
00592 int i, j;
00593
00594 if (adv == NULL) {
00595 DEBUG(DEBUG_FLAG, "NEWEST_FA: test_newest_fa() called with "
00596 "NULL adv\n");
00597 return 0;
00598 }
00599
00600 if (monitor_check_policy(NEWEST_FA_BIT) && adv->counter > 1)
00601 return 0;
00602
00603
00604
00605 adv->priority = MAXPRIORITY;
00606 DEBUG(DEBUG_FLAG, "mark_best_fa: newly arrived FA agent"
00607 " advertisement (%s) - policy NEWEST_FA\n",
00608 inet_ntoa(adv->addr));
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 DEBUG(DEBUG_FLAG, "NEWEST_FA: priorities\n");
00639 for (i = 0; i < MAX_INTERFACES; i++) {
00640 if (!mon_devs[i].in_use || !mon_devs[i].iwspy_support ||
00641 mon_devs[i].spy_number <= 0)
00642 continue;
00643
00644 for (j = 0; j < MAX_MONITOR; j++) {
00645 if (mon_devs[i].mon[j].active != 1)
00646 continue;
00647
00648 DEBUG(DEBUG_FLAG, "NEWEST_FA: FA=%s prio=%i\n",
00649 inet_ntoa(mon_devs[i].mon[j].adv->addr),
00650 mon_devs[i].mon[j].adv->priority);
00651
00652 if (mon_devs[i].mon[j].adv == adv ||
00653 mon_devs[i].mon[j].adv->priority <= 1)
00654 continue;
00655
00656 DEBUG(DEBUG_FLAG, "NEWEST_FA: setting other FA "
00657 "priority %i -> 1\n",
00658 mon_devs[i].mon[j].adv->priority);
00659 mon_devs[i].mon[j].adv->priority = 1;
00660 }
00661 }
00662
00663 return 1;
00664 }
00665
00666
00667
00668
00669
00670
00671
00672 static void prioritize_all(void)
00673 {
00674 int i, j;
00675 int p = mon_conf.dev_priority_percentage;
00676 struct agentadv_data *adv;
00677 struct monitor_address *mon;
00678
00679 for (i = 0; i < MAX_INTERFACES; i++) {
00680 if (!mon_devs[i].in_use || !mon_devs[i].iwspy_support ||
00681 mon_devs[i].spy_number <= 0)
00682 continue;
00683
00684 for (j = 0; j < MAX_MONITOR; j++) {
00685 if (mon_devs[i].mon[j].active != 1 ||
00686 mon_devs[i].mon[j].adv->priority <= 0)
00687 continue;
00688
00689 adv = mon_devs[i].mon[j].adv;
00690 assert(adv!=NULL);
00691 assert(adv->mon != NULL);
00692 mon = &mon_devs[i].mon[j];
00693 assert(mon!=NULL);
00694
00695
00696 adv->priority = (int)(((mon_devs[i].priority*p +
00697 mon->avg*(100-p)))/100.0);
00698
00699
00700
00701
00702
00703
00704 if (monitor_check_policy(EARLY_EXPIRE_BIT) &&
00705 mon_devs[i].vector_update[j] != 1) {
00706 adv->priority = (int)((adv->priority *
00707 (100-mon_conf.old_fa_factor))/100);
00708 DEBUG(DEBUG_FLAG, "(%d/%d) Not fresh! %-15s"
00709 " prio %d (factor: %d%%)\n",
00710 j+1, MAX_MONITOR, inet_ntoa(adv->addr),
00711 adv->priority, mon_conf.old_fa_factor);
00712 }
00713
00714
00715
00716
00717 if (adv->priority == 0)
00718 adv->priority = 1;
00719 }
00720 }
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730 static void monitor_balance_prio(void)
00731 {
00732 int curr_qual, i, j, max_index = -1;
00733 struct monitor_interface *curr_dev = NULL;
00734 struct monitor_interface *max_dev = NULL;
00735 int max_qual = 0;
00736 double d;
00737
00738 if (mon_conf.current_fa < 0 ||
00739 (*mon_conf.current_adv) == NULL) {
00740 DEBUG(DEBUG_FLAG, "monitor_balance_prio: current fa "
00741 "not known\n");
00742 return;
00743 }
00744
00745
00746 curr_dev = monitor_get_dev(mon_conf.current_dev);
00747 if (!curr_dev || !curr_dev->iwspy_support) {
00748 DEBUG(DEBUG_FLAG, "monitor_balance_prio: currently not "
00749 "using wireless device\n");
00750 return;
00751 }
00752 curr_qual = curr_dev->mon[mon_conf.current_fa].avg;
00753
00754
00755 for (i = 0; i < MAX_INTERFACES; i++) {
00756 if (mon_devs[i].in_use == 0 ||
00757 mon_devs[i].iwspy_support == 0 ||
00758 mon_devs[i].spy_number <= 0)
00759 continue;
00760
00761 for (j = 0; j < MAX_MONITOR; j++) {
00762 if (mon_devs[i].mon[j].active != 1)
00763 continue;
00764 if (mon_devs[i].mon[j].avg > max_qual) {
00765 max_dev = &mon_devs[i];
00766 max_qual = mon_devs[i].mon[j].avg;
00767 max_index = j;
00768 }
00769 }
00770 }
00771 if (max_index == -1) {
00772 DEBUG(DEBUG_FLAG, "monitor_balance_prio: no maximum!\n");
00773 return;
00774 }
00775 assert(max_dev != NULL);
00776
00777
00778 if (curr_dev->mon[mon_conf.current_fa].avg < mon_conf.min_balance) {
00779 DEBUG(DEBUG_FLAG, "monitor_balance_prio: quality too small."
00780 " No balancing (quality %d, min_balance %d)\n",
00781 curr_dev->mon[mon_conf.current_fa].avg,
00782 mon_conf.min_balance);
00783 return;
00784 }
00785
00786 if (max_dev->mon[max_index].avg>0)
00787 d = (double)(((double)curr_dev->mon[mon_conf.current_fa].avg)/
00788 ((double)max_dev->mon[max_index].avg));
00789 else
00790 d = 1.0;
00791
00792 DEBUG(DEBUG_FLAG, "monitor_balance_prio: current=%d, max=%d,"
00793 " divide=%f, (%d)threshold=%f\n",
00794 curr_dev->mon[mon_conf.current_fa].avg,
00795 max_dev->mon[max_index].avg, d,
00796 mon_conf.threshold,
00797 (double)(mon_conf.threshold/100.0));
00798 if(d < 1.0 && d > (mon_conf.threshold/100.0) &&
00799 max_dev->mon[max_index].adv->priority > 0) {
00800 curr_dev->mon[mon_conf.current_fa].adv->priority =
00801 max_dev->mon[max_index].adv->priority;
00802 DEBUG(DEBUG_FLAG, "monitor_balance_prio: "
00803 "Qualities near enough, balancing\n");
00804 }
00805 #ifdef PRINT_ENTRIES
00806 print_entries();
00807 #endif
00808 return;
00809 }
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 static int monitor_get_fa(void *data)
00825 {
00826 int i;
00827 struct agentadv_data *adv = NULL;
00828 struct monitor_interface *dev = NULL;
00829
00830 if (data) {
00831 adv = ((struct event_FA *)data)->adv;
00832 }
00833
00834 for (i = 0; i < MAX_INTERFACES; i++) {
00835 if (!mon_devs[i].in_use ||
00836 !mon_devs[i].iwspy_support ||
00837 mon_devs[i].spy_number <= 0)
00838 continue;
00839 }
00840
00841
00842 if (*mon_conf.current_adv == NULL)
00843 DEBUG(DEBUG_FLAG, "monitor_get_fa: Current adv "
00844 "pointer is NULL\n");
00845 else {
00846 DEBUG(DEBUG_FLAG, "monitor_get_fa: current_dev %s\n",
00847 mon_conf.current_dev);
00848 dev = monitor_get_dev(mon_conf.current_dev);
00849 }
00850
00851
00852 mon_conf.current_fa = -1;
00853 mark_new_entries();
00854
00855 if (dev != NULL && dev->iwspy_support && mon_conf.current_fa != -1 &&
00856 !strncmp(dev->ifname, mon_conf.current_dev, IFNAMSIZ)) {
00857 DEBUG(DEBUG_FLAG, "current FA: %-15s",
00858 inet_ntoa(dev->mon[mon_conf.current_fa].adv->addr));
00859 DEBUG(DEBUG_FLAG, " active %d, prio %d, avg %d\n",
00860 dev->mon[mon_conf.current_fa].active,
00861 dev->mon[mon_conf.current_fa].adv->priority,
00862 dev->mon[mon_conf.current_fa].avg);
00863 } else
00864 DEBUG(DEBUG_FLAG, "current FA: Not connected or "
00865 "FA in the non-wireless-extensions interface\n");
00866
00867
00868 if (adv != NULL &&
00869 (monitor_check_policy(NEWEST_FA_BIT) ||
00870 monitor_check_policy(NEWEST_ADV_BIT))) {
00871 DEBUG(DEBUG_FLAG, "NEWEST_FA/ADV policy\n");
00872 if (test_newest_fa(adv) && !adv->in_use)
00873 return 1;
00874
00875
00876
00877 if (monitor_check_policy(NEWEST_ADV_BIT))
00878 return 0;
00879 }
00880
00881 prioritize_all();
00882
00883 if (!monitor_check_policy(EAGER_SWITCH_BIT))
00884 monitor_balance_prio();
00885 else {
00886
00887 timerclear(mon_conf.reg_send_timer);
00888 }
00889
00890 return 0;
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 static int monitor_add_fa(void *data)
00904 {
00905 int ph;
00906 struct agentadv_data *adv = NULL;
00907 struct monitor_interface *dev;
00908 struct timeval tstamp;
00909 struct iw_quality avg_qual;
00910
00911 if (data) {
00912 adv = ((struct event_FA *)data)->adv;
00913 }
00914
00915
00916 dev = monitor_get_dev(adv->ifname);
00917 if (!dev || !dev->iwspy_support) {
00918 DEBUG(DEBUG_FLAG, "monitor_add_fa: Not a wireless "
00919 "interface (%s)\n", adv->ifname);
00920 return 1;
00921 }
00922
00923 gettimeofday(&tstamp,NULL);
00924
00925
00926 ph = monitor(dev, adv, tstamp);
00927 if (ph < 0 && ph != -3) {
00928 DEBUG(DEBUG_FLAG, "monitor_add_fa: failed to monitor\n");
00929 }
00930 if (ph >= 0)
00931 DEBUG(DEBUG_FLAG, "monitor_add_fa (index=%d): ip: %s - "
00932 "hw: %s\n", ph, inet_ntoa(dev->mon[ph].adv->addr),
00933 ether_hwtoa((unsigned char *)
00934 dev->mon[ph].adv->adv.from.sll_addr));
00935
00936
00937 if (mon_conf.rec_qual) {
00938 if (mon_rec_qual_initialized == 0) {
00939 rec_init();
00940 mon_rec_qual_initialized = 1;
00941 }
00942 avg_qual.qual = get_qual_avg(dev, adv->adv.from.sll_addr);
00943 avg_qual.level = 0;
00944 avg_qual.noise = 0;
00945 if (memcmp(adv->adv.from.sll_addr,
00946 ((*mon_conf.current_adv)->adv.from.sll_addr),
00947 ETH_ALEN) == 0) {
00948 DEBUG(DEBUG_FLAG, "monitor_add_fa: add quality "
00949 "record\n");
00950 rec_add((char *) adv->adv.from.sll_addr, &avg_qual,
00951 &tstamp, adv->addr);
00952 }
00953 } else if (mon_rec_qual_initialized) {
00954 DEBUG(DEBUG_FLAG, "monitor_add_fa: dump quality record\n");
00955 rec_dump(REC_DUMP_TYPE, -1);
00956 rec_clean_up();
00957 mon_rec_qual_initialized = 0;
00958 }
00959
00960 return ph;
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 static struct monitor_interface *monitor_dev_up(char *ifname)
00974 {
00975 int i, r;
00976 struct monitor_interface *dev = NULL;
00977 char buffer[(sizeof(struct iw_quality) +
00978 sizeof(struct sockaddr)) *
00979 (IW_MAX_SPY+1)];
00980
00981
00982 for (i = 0; i < MAX_INTERFACES; i++) {
00983 if (!mon_devs[i].in_use) {
00984 memset(&mon_devs[i], 0,
00985 sizeof(struct monitor_interface));
00986 dev = &mon_devs[i];
00987 break;
00988 }
00989 }
00990
00991 if (!dev) {
00992 DEBUG(DEBUG_FLAG, "monitor_dev_up: Free slots unavailable!\n");
00993 return NULL;
00994 }
00995
00996
00997 dev->sock = dyn_wireless_create_socket();
00998 if (dev->sock < 0) {
00999 DEBUG(DEBUG_FLAG, "monitor_dev_up - open wireless socket: "
01000 "%s\n", strerror(errno));
01001 return NULL;
01002 }
01003
01004
01005 memcpy(dev->ifname, ifname, IFNAMSIZ);
01006 if (dev->ifname == NULL) {
01007 DEBUG(DEBUG_FLAG, "monitor_dev_up: dev->ifname NULL!\n");
01008 return NULL;
01009 }
01010
01011
01012
01013 r = dyn_wireless_iwspy_get(dev->sock, dev->ifname, buffer);
01014 dev->iwspy_support = r == -1 ? 0 : 1;
01015 if (!dev->iwspy_support)
01016 DEBUG(DEBUG_FLAG, "monitor_dev_up: IWSPY not supported (%s)\n",
01017 dev->ifname);
01018
01019
01020
01021 r = dyn_wireless_iwspy_set(dev->sock, dev->ifname, NULL, 0);
01022 dev->iwspy_support = r == -1 ? 0 : 1;
01023 if (!dev->iwspy_support)
01024 DEBUG(DEBUG_FLAG, "monitor_dev_up: IWSPY not supported (%s)\n",
01025 dev->ifname);
01026
01027
01028 dev->channel = dyn_wireless_get_channel(dev->sock, dev->ifname);
01029 dev->channel_support = dev->channel_get_support =
01030 dev->channel == -1 ? 0 : 1;
01031 if (!dev->channel_support)
01032 DEBUG(DEBUG_FLAG, "monitor_dev_up: channel query not "
01033 "supported (%s)\n", dev->ifname);
01034 else
01035 DEBUG(DEBUG_FLAG, "monitor_dev_up: %s: channel %d\n",
01036 dev->ifname, dev->channel);
01037
01038
01039 if (mon_conf.default_ch >= 1)
01040 r = dyn_wireless_set_channel(dev->sock, dev->ifname,
01041 mon_conf.default_ch);
01042 else
01043 r = dyn_wireless_set_channel(dev->sock, dev->ifname,
01044 dev->channel);
01045
01046 dev->channel_support = r == -1 ? 0 : 1;
01047 if (!dev->channel_support)
01048 DEBUG(DEBUG_FLAG, "monitor_dev_up: set channel not "
01049 "supported (%s)\n", dev->ifname);
01050 else
01051 DEBUG(DEBUG_FLAG, "monitor_dev_up: set channel "
01052 "successful (%s, %d)\n", dev->ifname,
01053 dev->channel);
01054
01055
01056 if (dyn_wireless_get_range(dev->sock, dev->ifname, &dev->range)) {
01057 DEBUG(DEBUG_FLAG, "monitor_dev_up: get range of parameters "
01058 "not supported (%s)\n", dev->ifname);
01059
01060 #define MAX_QUAL 92
01061 dev->range.max_qual.qual = MAX_QUAL;
01062 } else {
01063
01064
01065 if (dev->range.max_qual.qual <= 0) {
01066 DEBUG(DEBUG_FLAG, "monitor_dev_up: max qual value is "
01067 "ZERO, assuming wvlan_cs driver and using 92 "
01068 "as the maximum\n");
01069 dev->range.max_qual.qual = MAX_QUAL;
01070 }
01071
01072 DEBUG(DEBUG_FLAG, "RANGE (%s):\n", dev->ifname);
01073 DEBUG(DEBUG_FLAG, "\tthroughput %d\n",
01074 dev->range.throughput);
01075 DEBUG(DEBUG_FLAG, "\tmin_nwid %d\n",
01076 dev->range.min_nwid);
01077 DEBUG(DEBUG_FLAG, "\tmax_nwid %d\n",
01078 dev->range.max_nwid);
01079 DEBUG(DEBUG_FLAG, "\tchannels %d\n",
01080 dev->range.num_channels);
01081 DEBUG(DEBUG_FLAG, "\tsensitivity %d\n",
01082 dev->range.sensitivity);
01083 DEBUG(DEBUG_FLAG, "\tmax_qual.qual %d\n",
01084 dev->range.max_qual.qual);
01085 DEBUG(DEBUG_FLAG, "\tmax_qual.level %d\n",
01086 dev->range.max_qual.level);
01087 DEBUG(DEBUG_FLAG, "\tmax_qual.noise %d\n",
01088 dev->range.max_qual.noise);
01089
01090 #if WIRELESS_EXT >= 9
01091
01092 #else
01093 DEBUG(DEBUG_FLAG, "\tmax_encoding.method %d\n",
01094 dev->range.max_encoding.method);
01095 #endif
01096
01097 #if WIRELESS_EXT >= 8
01098 DEBUG(DEBUG_FLAG, "\tnum_bitrates %d\n",
01099 dev->range.num_bitrates);
01100 DEBUG(DEBUG_FLAG, "\tmin_rts %d\n",
01101 dev->range.min_rts);
01102 DEBUG(DEBUG_FLAG, "\tmax_rts %d\n",
01103 dev->range.max_rts);
01104 DEBUG(DEBUG_FLAG, "\tmin_frag %d\n",
01105 dev->range.min_frag);
01106 DEBUG(DEBUG_FLAG, "\tmax_frag %d\n",
01107 dev->range.max_frag);
01108 #endif
01109 }
01110
01111 dev->in_use = 1;
01112 mon_conf.interfaces++;
01113
01114 if (!dev->channel_get_support && !dev->channel_support &&
01115 !dev->iwspy_support) {
01116 close(dev->sock);
01117 dev->sock = -1;
01118 }
01119
01120 return dev;
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 static int monitor_dev_down(struct monitor_interface *dev)
01133 {
01134 if (dev->in_use) {
01135 mon_conf.interfaces--;
01136 dev->in_use = 0;
01137 if (mon_conf.interfaces < 0) {
01138 mon_conf.interfaces = 0;
01139 DEBUG(DEBUG_FLAG, "monitor_dev_down: Negative "
01140 "interface count!\n");
01141 }
01142 if (!dev->iwspy_support)
01143 return 0;
01144
01145
01146 dyn_wireless_iwspy_set(dev->sock, dev->ifname, NULL, 0);
01147
01148 if (dev->sock >= 0) {
01149 close(dev->sock);
01150 dev->sock = -1;
01151 }
01152 mon_conf.iwspy_supported--;
01153 if (mon_conf.iwspy_supported < 0) {
01154 mon_conf.iwspy_supported = 0;
01155 DEBUG(DEBUG_FLAG, "monitor_dev_down: Negative "
01156 "iwspy_support count!\n");
01157 }
01158 } else
01159 return -1;
01160
01161 return 0;
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 static int monitor_interface_up(void *data)
01179 {
01180 struct monitor_interface *dev;
01181 char *ifname = NULL;
01182 struct timeval *last_reg_send_time = NULL;
01183 int *priority = NULL;
01184
01185 if (data) {
01186 ifname = ((struct event_INTERFACE *)data)->ifname;
01187 last_reg_send_time = ((struct event_INTERFACE *)
01188 data)->last_reg_send_time;
01189 mon_conf.current_adv = ((struct event_INTERFACE *)
01190 data)->current_adv;
01191 priority = ((struct event_INTERFACE *)data)->priority;
01192 }
01193
01194
01195 dev = monitor_dev_up(ifname);
01196 if (dev == NULL) {
01197 DEBUG(DEBUG_FLAG, "monitor_interface_up: no free slots\n");
01198 syslog(LOG_ERR, "monitor_interface_up: no free slots, %m");
01199 return -1;
01200 }
01201
01202
01203
01204 if (mon_conf.reg_send_timer == NULL)
01205 mon_conf.reg_send_timer = last_reg_send_time;
01206
01207
01208 if (dev->iwspy_support && mon_conf.iwspy_supported == 0) {
01209 handler_register(FA_ADV_EXPIRE, monitor_del_fa);
01210 handler_register(FA_ADV_RECEIVE, monitor_add_fa);
01211 #ifndef PLAIN_MIP
01212 handler_register(FA_GET, monitor_get_fa);
01213 #endif
01214 mon_conf.iwspy_supported++;
01215 DEBUG(DEBUG_FLAG, "monitor_interface_up: Handlers "
01216 "initialized (%s)\n", dev->ifname);
01217 if (mon_conf.rec_qual) {
01218 if (mon_rec_qual_initialized == 0) {
01219
01220
01221 rec_init();
01222 mon_rec_qual_initialized = 1;
01223 }
01224 } else if (mon_rec_qual_initialized) {
01225 rec_dump(REC_DUMP_TYPE, -1);
01226 rec_clean_up();
01227 mon_rec_qual_initialized = 0;
01228 }
01229 }
01230
01231
01232 if (priority != NULL && *priority >= 0)
01233 dev->priority = *priority;
01234 else
01235 if (dev->iwspy_support)
01236 dev->priority = DEFAULT_WIRELESS_PRIO;
01237 else
01238 dev->priority = DEFAULT_INTERFACE_PRIORITY;
01239
01240
01241 DEBUG(DEBUG_FLAG, "monitor_interface_up: iwspy: %s channel"
01242 " switch: %s\n",
01243 dev->iwspy_support ? "YES" : "NO",
01244 dev->channel_support ? "YES" : "NO");
01245
01246 if (dev->channel_support && dev->iwspy_support)
01247 return 0;
01248 else if (!dev->channel_support && dev->iwspy_support)
01249 return 1;
01250 else if (dev->channel_support && !dev->iwspy_support)
01251 return 2;
01252 else
01253 return 3;
01254 }
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 static int monitor_interface_down(void *data)
01268 {
01269 struct event_INTERFACE *vars = (struct event_INTERFACE *)data;
01270 struct monitor_interface *dev = NULL;
01271
01272 if (vars == NULL) {
01273 DEBUG(DEBUG_FLAG, "monitor_interface_down: NULL argument!\n");
01274 return -1;
01275 }
01276
01277 dev = monitor_get_dev(vars->ifname);
01278 if (!dev) {
01279 DEBUG(DEBUG_FLAG, "monitor_interface_down: Device not "
01280 "found! (%s)\n", vars->ifname);
01281 return -1;
01282 }
01283
01284 monitor_dev_down(dev);
01285
01286
01287 if (mon_conf.iwspy_supported == 0 && dev->iwspy_support) {
01288 handler_unregister(FA_ADV_EXPIRE, monitor_del_fa);
01289 handler_unregister(FA_ADV_RECEIVE, monitor_add_fa);
01290 #ifndef PLAIN_MIP
01291 handler_unregister(FA_GET, monitor_get_fa);
01292 #endif
01293 }
01294
01295 return 0;
01296 }
01297
01298
01299
01300
01301
01302
01303 int MONITOR_unregister_module(void)
01304 {
01305 int i;
01306
01307 for (i = 0; i < MAX_INTERFACES; i++) {
01308 if (!mon_devs[i].in_use)
01309 continue;
01310 if (mon_devs[i].iwspy_support && !mon_conf.SQ_cache)
01311 dyn_wireless_iwspy_set(mon_devs[i].sock,
01312 mon_devs[i].ifname, NULL, 0);
01313
01314 if (mon_devs[i].sock >= 0) {
01315 close(mon_devs[i].sock);
01316 mon_devs[i].sock = -1;
01317 }
01318 }
01319
01320 if (mon_rec_qual_initialized) {
01321 if (mon_conf.rec_qual)
01322 rec_dump(REC_DUMP_TYPE, -1);
01323 rec_clean_up();
01324 mon_rec_qual_initialized = 0;
01325 }
01326
01327 return 0;
01328 }
01329
01330
01331 void MONITOR_register_module(void)
01332 {
01333
01334 memset(&mon_conf, 0, sizeof(struct monitor_global_data));
01335 mon_conf.current_fa = -1;
01336 mon_conf.current_adv = NULL;
01337 mon_conf.reg_send_timer = NULL;
01338 mon_conf.interfaces = 0;
01339 mon_conf.iwspy_supported = 0;
01340 mon_conf.threshold = DEFAULT_THRESHOLD;
01341 mon_conf.default_ch = -1;
01342 mon_conf.old_fa_factor = OLD_FA_FACTOR;
01343 mon_conf.expiretime = DEFAULT_EARLY_EXPIRE_TIME;
01344 mon_conf.min_balance = DEFAULT_MIN_BALANCE;
01345 mon_conf.worst_min_time = DEFAULT_WORST_MIN_TIME;
01346 mon_conf.worst_max_time = DEFAULT_WORST_MAX_TIME;
01347 mon_conf.dev_priority_percentage = DEFAULT_DEV_PRIO_PERCENT;
01348 mon_conf.average_length = DEFAULT_AVG_LEN;
01349 mon_conf.rec_qual = 0;
01350 mon_conf.SQ_cache = 0;
01351 mon_rec_qual_initialized = 0;
01352 memset(mon_devs, 0, sizeof(mon_devs));
01353
01354
01355 handler_register(INTERFACE_INIT, monitor_interface_up);
01356 handler_register(INTERFACE_DOWN, monitor_interface_down);
01357 }
01358
01359
01360 void monitor_poll_ap_addresses(struct mn_data *mn)
01361 {
01362 int i, j;
01363 char new_addr[ETH_ALEN];
01364
01365 DEBUG(DEBUG_FLAG, "monitor_poll_ap_addresses()\n");
01366 for (i = 0; i < MAX_INTERFACES; i++) {
01367 if (!mon_devs[i].in_use || mon_devs[i].sock < 0)
01368 continue;
01369
01370 if (dyn_wireless_get_ap_address(mon_devs[i].sock,
01371 mon_devs[i].ifname,
01372 new_addr) < 0) {
01373 DEBUG(DEBUG_FLAG, "monitor_poll_ap_addresses: get AP "
01374 "hw addr failed\n");
01375 continue;
01376 }
01377
01378 if (memcmp(new_addr, mon_devs[i].ap_hwaddr, ETH_ALEN) != 0) {
01379 DEBUG(DEBUG_FLAG, "Monitor: AP hw addr changed "
01380 "(iface=%s): %s => ",
01381 mon_devs[i].ifname,
01382 ether_hwtoa((unsigned char *)
01383 mon_devs[i].ap_hwaddr));
01384 DEBUG(DEBUG_FLAG, "%s\n",
01385 ether_hwtoa((unsigned char *) new_addr));
01386
01387 for (j = 0; j < MAX_INTERFACES; j++) {
01388 if (strcmp(mon_devs[i].ifname,
01389 mn->iface[j].device) != 0 ||
01390 mn->iface[j].s < 0)
01391 continue;
01392
01393 send_agent_solicitation(mn->iface[j].s);
01394 }
01395 memcpy(mon_devs[i].ap_hwaddr, new_addr, ETH_ALEN);
01396 }
01397 }
01398 }