00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <malloc.h>
00015 #include <unistd.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <getopt.h>
00019 #include <signal.h>
00020 #include <errno.h>
00021 #include <asm/types.h>
00022 #include <sys/types.h>
00023 #include <sys/socket.h>
00024 #include <sys/ioctl.h>
00025 #include <sys/time.h>
00026 #include <linux/wireless.h>
00027 #include "owntypes.h"
00028 #include <linux/filter.h>
00029 #include <netinet/ip_icmp.h>
00030 #include <netinet/ip.h>
00031 #include <features.h>
00032
00033 #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
00034 #include <netpacket/packet.h>
00035 #include <net/ethernet.h>
00036 #include <netinet/if_ether.h>
00037 #else
00038 #include <linux/if_packet.h>
00039 #include <linux/if_ether.h>
00040 #endif
00041
00042 #include "debug.h"
00043 #include "agentadv.h"
00044 #include "dyn_wireless.h"
00045 #include "monitor.h"
00046 #include "fixed_fd_zero.h"
00047 #include "util.h"
00048 #include "dyn_iwspy_rec.h"
00049
00050 #define DEBUG_FLAG '5'
00051 #define TIME_ERROR 10000
00052 #define DEFAULT_INTERVAL 1000000
00053 #define USAGE "iwspy_gather [-h] [-v] -d <device_name> [-i <msecs>] [-l <seconds>]\n"\
00054 "Options:\n"\
00055 "\t-h\t\t\thelp (--help)\n"\
00056 "\t-v\t\t\tverbose (--verbose)\n"\
00057 "\t-d <name>\t\tdevice (--device)\n"\
00058 "\t-i <milliseconds>\tchecking interval in milliseconds (--interval)\n"\
00059 "\t-l <seconds>\t\tmonitoring length in seconds (--length)\n"
00060
00061 extern int opt_debug;
00062
00063 static struct option const long_options[] =
00064 {
00065 {"interval", required_argument, NULL, 'i'},
00066 {"interactive", no_argument, NULL, 'a'},
00067 {"help", no_argument, NULL, 'h'},
00068 {"device", required_argument, NULL, 'd'},
00069 {"length", required_argument, NULL, 'l'},
00070 {"verbose", no_argument, NULL, 'v'},
00071 {0, 0, 0, 0}
00072 };
00073
00074 int iwspy_sock, bcast_sock, adver_sock, interval;
00075 char ifname[IFNAMSIZ];
00076 char cache[ETH_ALEN*IW_MAX_SPY+1];
00077
00078
00079 static int add_check_mark(struct timeval *tstamp)
00080 {
00081 char buffer[(sizeof(struct iw_quality) +
00082 sizeof(struct sockaddr)) *
00083 (IW_MAX_SPY+1)];
00084 int monitored, i;
00085 struct sockaddr *hws;
00086 struct iw_quality *qual;
00087
00088 monitored = dyn_wireless_iwspy_get(iwspy_sock, ifname, buffer);
00089 if (monitored < 0) {
00090 fprintf(stderr, "add_check_mark: get iwspy failed\n");
00091 return 1;
00092 }
00093 hws = (struct sockaddr *)buffer;
00094 qual = (struct iw_quality *)
00095 (buffer + (sizeof(struct sockaddr) * monitored));
00096
00097 for (i = 0 ; i < monitored; i++) {
00098 if (qual[i].updated) {
00099 if (rec_add_qual(hws[i].sa_data, &qual[i], tstamp))
00100 fprintf(stderr, "add_check_mark: rec_add_qual "
00101 "failed\n");
00102 } else
00103 DEBUG(DEBUG_FLAG, "add_check_mark: monitored entry "
00104 "not updated (%d)\n", i);
00105 }
00106
00107 return 0;
00108 }
00109
00110
00111 static int check_monitored(unsigned char *hw, struct in_addr addr)
00112 {
00113 char buffer[(sizeof(struct iw_quality) +
00114 sizeof(struct sockaddr)) *
00115 (IW_MAX_SPY+1)];
00116 static int in_cache = 0;
00117 int i, monitored;
00118 struct sockaddr *hws;
00119 struct iw_quality *qual;
00120 struct timeval t;
00121
00122
00123
00124 for (i = 0 ; i < in_cache; i++)
00125 if(!(memcmp(&cache[i*ETH_ALEN], hw, ETH_ALEN)))
00126 return 0;
00127
00128 monitored = dyn_wireless_iwspy_get(iwspy_sock, ifname, buffer);
00129 if (monitored < 0) {
00130 fprintf(stderr, "get_iwspy failed\n");
00131 return -1;
00132 }
00133 hws = (struct sockaddr *)buffer;
00134 qual = (struct iw_quality *)
00135 (buffer + (sizeof(struct sockaddr) * monitored));
00136
00137 DEBUG(DEBUG_FLAG, "check_monitored: monitored = %d\n", monitored);
00138 if (monitored >= MAX_MONITOR)
00139 return 1;
00140
00141 memcpy(hws[monitored].sa_data, hw, ETH_ALEN);
00142 monitored++;
00143 if (dyn_wireless_iwspy_set(iwspy_sock, ifname, buffer,
00144 monitored) < 0) {
00145 fprintf(stderr, "set_iwspy failed!\n");
00146 return -1;
00147 } else {
00148 gettimeofday(&t, NULL);
00149 rec_add_long(hws, hw, addr, qual, &t, monitored);
00150 }
00151 memcpy(&cache[in_cache*ETH_ALEN], hw, ETH_ALEN);
00152 in_cache++;
00153
00154 return 0;
00155 }
00156
00157
00158 #define MAX_ADV_RADDRS 10
00159 #define MAX_ADV_COADDRS 10
00160 static int collect_stats(unsigned long const ival, long const length)
00161 {
00162 char buf[MAX_ADV_MSG];
00163 struct adv_extensions adv;
00164 fd_set rfds;
00165 struct in_addr ip_addr;
00166 struct timeval last_sol, tv;
00167 int current, retval = 0;
00168 static int monitoring = 0;
00169 unsigned long passed, diff = 0;
00170
00171
00172 FD_ZERO(&rfds);
00173 gettimeofday(&last_sol, NULL);
00174 current = 0;
00175 DEBUG(DEBUG_FLAG, "interval = %lu\n", ival);
00176
00177 for (;;) {
00178 gettimeofday(&tv, NULL);
00179 passed = usec_passed(&last_sol, &tv);
00180 if (length > 0 && tv.tv_sec > length)
00181 return 0;
00182
00183 if (passed >= (ival - TIME_ERROR) ) {
00184
00185 add_check_mark(&tv);
00186 }
00187
00188 if (retval > 0 && FD_ISSET(adver_sock, &rfds)) {
00189 if (handle_icmp_adv(adver_sock, buf, MAX_ADV_MSG,
00190 &adv) == 1) {
00191 ip_addr.s_addr = adv.ip->saddr;
00192 monitoring =
00193 check_monitored(adv.from.sll_addr,
00194 ip_addr);
00195 } else {
00196 fprintf(stderr, "handle_icmp_adv failed\n");
00197 }
00198 }
00199
00200 if (passed >= (ival - TIME_ERROR) ) {
00201
00202 if (send_agent_solicitation(bcast_sock) < 0)
00203 fprintf(stderr, "send_agent_solicitation "
00204 "failed!\n");
00205 else {
00206 gettimeofday(&last_sol, NULL);
00207 diff = usec_passed(&tv, &last_sol);
00208 }
00209 if (ival - diff > 0)
00210 set_usecs(&tv, ival - diff);
00211 else
00212 continue;
00213 } else {
00214 if (ival - passed > 0)
00215 set_usecs(&tv, ival - passed);
00216 else
00217 continue;
00218
00219
00220
00221 }
00222
00223 FD_ZERO(&rfds);
00224 if (!monitoring)
00225 FD_SET(adver_sock, &rfds);
00226
00227 retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
00228 }
00229
00230 return -1;
00231 }
00232
00233
00234 static void clean_up(int signal)
00235 {
00236
00237 rec_dump(3, interval);
00238 rec_clean_up();
00239
00240 dyn_wireless_iwspy_set(iwspy_sock, ifname, NULL, 0);
00241 close(iwspy_sock);
00242 close(bcast_sock);
00243 close(adver_sock);
00244 exit(0);
00245 }
00246
00247
00248 static int init_sockets(void)
00249 {
00250 __u32 filter = 0;
00251
00252 filter = ICMP_FILTER_MN;
00253 iwspy_sock = dyn_wireless_create_socket();
00254 bcast_sock = open_agent_icmp_socket(ifname, filter);
00255 adver_sock = open_agent_icmp_adv_socket(ifname, AGENTADV_FILTER_ADV);
00256
00257 if (iwspy_sock < 0 || bcast_sock < 0 || adver_sock < 0)
00258 return 1;
00259 return 0;
00260 }
00261
00262
00263 int main(int argc, char **argv)
00264 {
00265 unsigned long length = 0;
00266 int ret = -1, c, oindex;
00267 struct timeval end;
00268
00269 interval = -1;
00270
00271 if (fopen("/var/run/dynamics_mn_read", "r") != NULL ||
00272 fopen("/var/run/dynamics_mn_admin", "r") != NULL) {
00273 fprintf(stderr, "Don't run Mobile Node and iwspy_gather "
00274 "together. Exiting..\n");
00275 return 1;
00276 }
00277
00278
00279 while ((c = getopt_long(argc, argv, "i:d:hl:v", long_options,
00280 &oindex))
00281 != EOF) {
00282 switch (c) {
00283 case 'i':
00284 DEBUG(DEBUG_FLAG, "option i (Interval) with value"
00285 " '%s'\n", optarg);
00286 interval = atoi(optarg);
00287 break;
00288 case 'd':
00289 DEBUG(DEBUG_FLAG, "option d (Device) with value"
00290 " '%s'\n", optarg);
00291 ret = dyn_wireless_get_ifname(optarg, ifname);
00292 break;
00293 case 'l':
00294 DEBUG(DEBUG_FLAG, "option l (Length) with value"
00295 " '%s'\n", optarg);
00296 length = atol(optarg);
00297 if (length <= 0) {
00298 fprintf(stderr, "length must be >0!\n");
00299 return 1;
00300 }
00301 gettimeofday(&end, NULL);
00302 length += end.tv_sec;
00303 break;
00304 case 'v':
00305 opt_debug = 1;
00306 break;
00307 case 'h':
00308 default:
00309 printf(USAGE);
00310 return 1;
00311 }
00312 }
00313
00314
00315 if (ret < 0) {
00316 fprintf(stderr, "No device argument!\n");
00317 printf(USAGE);
00318 return 1;
00319 }
00320
00321
00322 if (interval >= 0 && interval < 10) {
00323 fprintf(stderr, "Interval must be at least 10 msecs\n");
00324 return 2;
00325 }
00326
00327
00328 if (init_sockets()) {
00329 fprintf(stderr, "Open socket(s) failed\n");
00330 return 3;
00331 }
00332
00333
00334 signal(SIGTERM, clean_up);
00335 signal(SIGINT, clean_up);
00336 signal(SIGHUP, clean_up);
00337
00338
00339 if (rec_init() < 0) {
00340 fprintf(stderr, "Recorder initialization failed!\n");
00341 return 4;
00342 }
00343
00344
00345 memset(cache, 0, sizeof(cache));
00346
00347
00348 if (interval < 0)
00349 collect_stats(DEFAULT_INTERVAL, length);
00350 else
00351 collect_stats((unsigned long)(interval*1000), length);
00352
00353 clean_up(0);
00354 return 0;
00355 }