📄 iwspy-gather.c
字号:
/* $Id: iwspy-gather.c,v 1.13 2001/08/16 14:15:38 jm Exp $ * Dynamics iwspy quality statistics collector module * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */#include <stdio.h>#include <malloc.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <signal.h>#include <errno.h>#include <asm/types.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/time.h>#include <linux/wireless.h>#include "owntypes.h"#include <linux/filter.h>#include <netinet/ip_icmp.h>#include <netinet/ip.h>#include <features.h> /* for the glibc version number */#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1#include <netpacket/packet.h>#include <net/ethernet.h> /* the L2 protocols */#include <netinet/if_ether.h>#else#include <linux/if_packet.h>#include <linux/if_ether.h> /* The L2 protocols */#endif#include "debug.h"#include "agentadv.h"#include "dyn_wireless.h"#include "monitor.h"#include "fixed_fd_zero.h"#include "util.h"#include "dyn_iwspy_rec.h"#define DEBUG_FLAG '5'#define TIME_ERROR 10000#define DEFAULT_INTERVAL 1000000 /* in usecs */#define USAGE "iwspy_gather [-h] [-v] -d <device_name> [-i <msecs>] [-l <seconds>]\n"\"Options:\n"\"\t-h\t\t\thelp (--help)\n"\"\t-v\t\t\tverbose (--verbose)\n"\"\t-d <name>\t\tdevice (--device)\n"\"\t-i <milliseconds>\tchecking interval in milliseconds (--interval)\n"\"\t-l <seconds>\t\tmonitoring length in seconds (--length)\n"extern int opt_debug;static struct option const long_options[] ={ {"interval", required_argument, NULL, 'i'}, {"interactive", no_argument, NULL, 'a'}, {"help", no_argument, NULL, 'h'}, {"device", required_argument, NULL, 'd'}, {"length", required_argument, NULL, 'l'}, {"verbose", no_argument, NULL, 'v'}, {0, 0, 0, 0}};int iwspy_sock, bcast_sock, adver_sock, interval;char ifname[IFNAMSIZ];char cache[ETH_ALEN*IW_MAX_SPY+1];static int add_check_mark(struct timeval *tstamp){ char buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * (IW_MAX_SPY+1)]; int monitored, i; struct sockaddr *hws; struct iw_quality *qual; monitored = dyn_wireless_iwspy_get(iwspy_sock, ifname, buffer); if (monitored < 0) { fprintf(stderr, "add_check_mark: get iwspy failed\n"); return 1; } hws = (struct sockaddr *)buffer; qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * monitored)); for (i = 0 ; i < monitored; i++) { if (qual[i].updated) { if (rec_add_qual(hws[i].sa_data, &qual[i], tstamp)) fprintf(stderr, "add_check_mark: rec_add_qual " "failed\n"); } else DEBUG(DEBUG_FLAG, "add_check_mark: monitored entry " "not updated (%d)\n", i); } return 0; }static int check_monitored(unsigned char *hw, struct in_addr addr){ char buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * (IW_MAX_SPY+1)]; static int in_cache = 0; int i, monitored; struct sockaddr *hws; struct iw_quality *qual; struct timeval t; /* already monitored? */ for (i = 0 ; i < in_cache; i++) if(!(memcmp(&cache[i*ETH_ALEN], hw, ETH_ALEN))) return 0; monitored = dyn_wireless_iwspy_get(iwspy_sock, ifname, buffer); if (monitored < 0) { fprintf(stderr, "get_iwspy failed\n"); return -1; } hws = (struct sockaddr *)buffer; qual = (struct iw_quality *) (buffer + (sizeof(struct sockaddr) * monitored)); DEBUG(DEBUG_FLAG, "check_monitored: monitored = %d\n", monitored); if (monitored >= MAX_MONITOR) return 1; memcpy(hws[monitored].sa_data, hw, ETH_ALEN); monitored++; if (dyn_wireless_iwspy_set(iwspy_sock, ifname, buffer, monitored) < 0) { fprintf(stderr, "set_iwspy failed!\n"); return -1; } else { gettimeofday(&t, NULL); rec_add_long(hws, hw, addr, qual, &t, monitored); } memcpy(&cache[in_cache*ETH_ALEN], hw, ETH_ALEN); in_cache++; return 0;}#define MAX_ADV_RADDRS 10#define MAX_ADV_COADDRS 10static int collect_stats(unsigned long const ival, long const length){ char buf[MAX_ADV_MSG]; struct adv_extensions adv; fd_set rfds; struct in_addr ip_addr; struct timeval last_sol, tv; int current, retval = 0; static int monitoring = 0; unsigned long passed, diff = 0; FD_ZERO(&rfds); gettimeofday(&last_sol, NULL); current = 0; DEBUG(DEBUG_FLAG, "interval = %lu\n", ival); for (;;) { gettimeofday(&tv, NULL); passed = usec_passed(&last_sol, &tv); if (length > 0 && tv.tv_sec > length) return 0; if (passed >= (ival - TIME_ERROR) ) { /* check mark */ add_check_mark(&tv); } if (retval > 0 && FD_ISSET(adver_sock, &rfds)) { if (handle_icmp_adv(adver_sock, buf, MAX_ADV_MSG, &adv) == 1) { ip_addr.s_addr = adv.ip->saddr; monitoring = check_monitored(adv.from.sll_addr, ip_addr); } else { fprintf(stderr, "handle_icmp_adv failed\n"); } } if (passed >= (ival - TIME_ERROR) ) { /* send agent solicitation */ if (send_agent_solicitation(bcast_sock) < 0) fprintf(stderr, "send_agent_solicitation " "failed!\n"); else { gettimeofday(&last_sol, NULL); diff = usec_passed(&tv, &last_sol); } if (ival - diff > 0) set_usecs(&tv, ival - diff); else continue; } else { if (ival - passed > 0) set_usecs(&tv, ival - passed); else continue;/* DEBUG(DEBUG_FLAG, "increase time value (diff %lu, " "wait %lu)\n", ival-passed, tv.tv_sec * 1000000+tv.tv_usec); */ } FD_ZERO(&rfds); if (!monitoring) FD_SET(adver_sock, &rfds); /* sleep */ retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); } return -1; /* never reached */}static void clean_up(int signal){ /* Make data files */ rec_dump(3, interval); rec_clean_up(); /* remove monitored entries from kernel */ dyn_wireless_iwspy_set(iwspy_sock, ifname, NULL, 0); close(iwspy_sock); close(bcast_sock); close(adver_sock); exit(0);}static int init_sockets(void){ __u32 filter = 0; filter = ICMP_FILTER_MN; iwspy_sock = dyn_wireless_create_socket(); bcast_sock = open_agent_icmp_socket(ifname, filter); adver_sock = open_agent_icmp_adv_socket(ifname, AGENTADV_FILTER_ADV); if (iwspy_sock < 0 || bcast_sock < 0 || adver_sock < 0) return 1; return 0;}int main(int argc, char **argv){ unsigned long length = 0; int ret = -1, c, oindex; struct timeval end; interval = -1; if (fopen("/var/run/dynamics_mn_read", "r") != NULL || fopen("/var/run/dynamics_mn_admin", "r") != NULL) { fprintf(stderr, "Don't run Mobile Node and iwspy_gather " "together. Exiting..\n"); return 1; } /* parse arguments */ while ((c = getopt_long(argc, argv, "i:d:hl:v", long_options, &oindex)) != EOF) { switch (c) { case 'i': /* interval */ DEBUG(DEBUG_FLAG, "option i (Interval) with value" " '%s'\n", optarg); interval = atoi(optarg); break; case 'd': /* device */ DEBUG(DEBUG_FLAG, "option d (Device) with value" " '%s'\n", optarg); ret = dyn_wireless_get_ifname(optarg, ifname); break; case 'l': /* stop after <arg> seconds */ DEBUG(DEBUG_FLAG, "option l (Length) with value" " '%s'\n", optarg); length = atol(optarg); if (length <= 0) { fprintf(stderr, "length must be >0!\n"); return 1; } gettimeofday(&end, NULL); length += end.tv_sec; break; case 'v': /* verbose */ opt_debug = 1; break; case 'h': /* Usage */ default: printf(USAGE); return 1; } } /* interface given? */ if (ret < 0) { fprintf(stderr, "No device argument!\n"); printf(USAGE); return 1; } /* decent range? */ if (interval >= 0 && interval < 10) { fprintf(stderr, "Interval must be at least 10 msecs\n"); return 2; } /* open sockets */ if (init_sockets()) { fprintf(stderr, "Open socket(s) failed\n"); return 3; } /* Setup signal handler */ signal(SIGTERM, clean_up); signal(SIGINT, clean_up); signal(SIGHUP, clean_up); /* initialize quality recorder database */ if (rec_init() < 0) { fprintf(stderr, "Recorder initialization failed!\n"); return 4; } /* clear cache */ memset(cache, 0, sizeof(cache)); /* begin harvesting */ if (interval < 0) collect_stats(DEFAULT_INTERVAL, length); else collect_stats((unsigned long)(interval*1000), length); clean_up(0); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -