⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iwspy-gather.c

📁 mobile ip 在linux下的一种实现
💻 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 + -