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

📄 dyn_iwspy_rec.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: dyn_iwspy_rec.c,v 1.13 2000/04/06 07:26:52 jm Exp $ * Dynamics iwspy recorder module * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2000, 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 <stdlib.h>#include <errno.h>#include <string.h>#include <assert.h>#include <asm/types.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <linux/wireless.h>#include "util.h"#include "hashtable.h"#include "dyn_iwspy_rec.h"#include "debug.h"#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endif#define DEBUG_FLAG '5'/* gnuplot headers */#define IMG_X 1000   /* single node image */#define IMG_Y 300#define G_IMG_X 1500 /* group node image */#define G_IMG_Y 400#define Q_RANGE 100  /* quality range: 0 - Q_RANGE */static struct hashtable *rec_hash;static int rec_num;struct timeval start_time;int new_dump = 1;static int hashfunc(void *key, const int hashsize){	__u8 hash;	__u32 data;	data = *((__u32 *) key); /* 32 least significant bytes 				   of the mac address */	hash = (__u8)((data & 0xff000000) >> 24) ^		(__u8)((data & 0x00ff0000) >> 16) ^		(__u8)((data & 0x0000ff00) >> 8) ^		(__u8)(data & 0x000000ff);	return ((int) hash);}/* * Comparison function for hashtable * * Arguments: *  key        First data structure *  cmprd      Second data structure * * Return: *  0          Not equal *  1          Equal */static int cmpfunc(void *key, struct node *cmprd){	__u32 data1;	struct hw_record *data2;	if (key == NULL) {		DEBUG(DEBUG_FLAG, "rec, cmpfunc:\n"		      "value for argument 'key' was NULL !\n"		      "Illegal value, returning 0 ! \n");		return 0;	}	if (cmprd == NULL) {		DEBUG(DEBUG_FLAG, "rec, cmpfunc:\n"		      "value for argument 'cmpd' was NULL !\n"		      "Illegal value, returning 0 ! \n");		return 0;	}	data1 = *((__u32 *)key);	data2 = (struct hw_record *) cmprd;	/* Compare the 32 least significant bits of the mac address */        if (!memcmp(&data1, &data2->hw[2], sizeof(__u32)))		return 1;	return 0;}int rec_init(void){	/* initialize hash */	rec_num = 0;	rec_hash = NULL;	rec_hash = hashtable_init(REC_HASH_SIZE);	if (rec_hash == NULL)		return -1;		return 0;}int rec_clean(struct node *node, void *data){	struct hw_record *entry = (struct hw_record *) node;	struct qual_entry *list = entry->quals;	struct qual_entry *tmp;	DEBUG(DEBUG_FLAG, "rec_clean\n");	while (list != NULL) {		tmp = list;		list = list->next;		free(tmp);	}	hashtable_remove(node);	free(entry);	new_dump = 1;		return 1;}void rec_clean_up(void){	DEBUG(DEBUG_FLAG, "rec_clean_up\n");	if (rec_hash == NULL)		return;	hashtable_iterator(rec_hash, rec_clean, NULL);	hashtable_destroy(rec_hash);	rec_hash = NULL;}static struct qual_entry *alloc_qual_entry(void){	struct qual_entry *qual;	qual = (struct qual_entry *)		malloc(sizeof(struct qual_entry));	if (!qual) {		DEBUG(DEBUG_FLAG, "alloc_qual_entry: malloc failed\n");		return NULL;	}	memset(qual, 0, sizeof(struct qual_entry));	return qual;}/* Add new quals node to old mac entry */static int qual_add(struct hw_record *rec, 		    struct iw_quality *qual,		    struct timeval *t){	struct qual_entry *entry;	unsigned int c;	if (!rec->quals) {	/* first qual entry? */		rec->quals = alloc_qual_entry();		if (!rec->quals) {			DEBUG(DEBUG_FLAG, "qual_add:"			      "alloc_qual_entry failed\n");			return -1;		}		rec->tail = rec->quals;	} else if (rec->tail->current >= REC_NODE_CHUNK) {		DEBUG(DEBUG_FLAG, "qual_add: New CHUNK\n");		/* time to allocate one chunk more */		rec->tail->next = (struct qual_entry *)			malloc(sizeof(struct qual_entry));		if (!rec->tail->next) {			DEBUG(DEBUG_FLAG, "qual_add:"			      " malloc failed\n");			return -1;		}		rec->tail = rec->tail->next;		memset(rec->tail, 0, sizeof(struct qual_entry));	}	entry = rec->tail;	c = entry->current;	assert(c >= 0 && c <= REC_NODE_CHUNK);	/* vector structure */	if (qual->qual > 200)		entry->qual[c].qual = 0;	else		entry->qual[c].qual = qual->qual;	entry->qual[c].level = qual->level;	entry->qual[c].noise = qual->noise;	entry->tstamp[c].tv_sec = t->tv_sec;	entry->tstamp[c].tv_usec = t->tv_usec;	entry->current++;		DEBUG(DEBUG_FLAG, "qual_add: %s - %d\n", 	      inet_ntoa(rec->ip_addr), entry->current);	return 0;}int rec_add_qual(char *hw, struct iw_quality *qual, struct timeval *tstamp){	struct hw_record *recs;	int ret;	assert(rec_hash != NULL);	recs = (struct hw_record *) 		hashtable_fetch(rec_hash, hashfunc, &hw[2], cmpfunc);	if (!recs) {		DEBUG(DEBUG_FLAG, "rec_add_qual: record not found!\n");		return 1;	}	ret = qual_add(recs, qual, tstamp);	if (ret < 0)		DEBUG(DEBUG_FLAG, "rec_add_qual: qual entry add failed\n");	return ret;}int rec_add(char *hw, struct iw_quality *qual, struct timeval *t,	    struct in_addr addr) {	struct hw_record *recs;	int ret;	if (new_dump) {		new_dump = 0;		start_time.tv_sec = t->tv_sec;		start_time.tv_usec = t->tv_usec;		DEBUG(DEBUG_FLAG, "rec_add: start time %ld\n",		      start_time.tv_sec);	}	assert(rec_hash != NULL);	recs = (struct hw_record *) 		hashtable_fetch(rec_hash, hashfunc, &hw[2], 				cmpfunc);	if (recs) {		/* old mac found. Add to that */		ret = qual_add(recs, qual, t);		if (ret < 0)			DEBUG(DEBUG_FLAG, "rec_add: qual entry add failed "			      "(old mac)\n");		return ret;	}	/* mac not found. Add new one */	recs = (struct hw_record *) malloc(sizeof(struct hw_record));	if (!recs) {		DEBUG(DEBUG_FLAG, "rec_add: malloc failed\n");		/* FIX: Add record dumping into files and free                   memory. Then initialize new list and continue                   recording. */		return -1;	}	memcpy(recs->hw, hw, ETH_ALEN);	recs->ip_addr.s_addr = addr.s_addr;	recs->quals = NULL;	recs->tail = recs->quals;	/* Add mac entry */	list_init_node(&recs->hashnode);	ret = hashtable_add(rec_hash, hashfunc, &hw[2], &recs->hashnode);	if (ret != TRUE) {		DEBUG(DEBUG_FLAG, "rec_add: hashtable_add failed\n");		return -1;	}	rec_num++;	/* Add new qual node to the mac entry */	ret = qual_add(recs, qual, t);	if (ret < 0) {		DEBUG(DEBUG_FLAG, "rec_add: qual entry add "		      "failed (new mac)\n");		return -1;	}	return ret;}int rec_add_long(struct sockaddr *hwa, unsigned char *hw,		 struct in_addr addr, struct iw_quality *qual, 		 struct timeval *t, int monitored){	int index = -1, i;		DEBUG(DEBUG_FLAG, "rec_add_long (%s)\n",	      inet_ntoa(addr));	for (i = 0 ; i < monitored; i++) {		if (!(memcmp(hwa[i].sa_data, hw, ETH_ALEN)))			index = i;	}	if (index < 0) {		DEBUG(DEBUG_FLAG, "rec_add: MAC address not found\n");		return -1;	}	return (rec_add((char *)&(hwa[index].sa_data), &qual[index], t, addr));}/**********************//* Dump data to files *//**********************/static int dump_fa(struct node *node, void *data){	struct hw_record *rec = (struct hw_record *) node;	struct qual_entry *qual = rec->quals;	FILE *fd, *header;	char name[FILENAME_MAX];	unsigned int i, len;	unsigned long range_sec = 0, range_dmsec = 0;#ifdef TEST	unsigned long diff;#endif	long range_usec = 0;	struct dump *info = (struct dump *)data;		/* open file */	snprintf(name, FILENAME_MAX, "FA-%s-dump.dat",		 inet_ntoa(rec->ip_addr));	fd = fopen(name, "w");	if (!fd) {		DEBUG(DEBUG_FLAG, "dump_fa: fopen: %s\n",		      strerror(errno));		return -1;	}		/* Print filetype info */	fprintf(fd, "# %d %d\n", info->interval, info->output_type);	/* Printf addresses */	fprintf(fd, "# %s %s\n", inet_ntoa(rec->ip_addr), 		ether_hwtoa((unsigned char *)rec->hw));        i = 0;	while (qual != NULL && i <= qual->current-1) {		/* write entry */		range_sec = qual->tstamp[i].tv_sec - start_time.tv_sec;		if (info->output_type == 1) { /* timestamp, seconds */			fprintf(fd, "%lu %u\n", range_sec, qual->qual[i].qual);		} else if (info->output_type == 2) { /* timestamp, 							dmsec, difference */			range_usec = qual->tstamp[i].tv_usec -				start_time.tv_usec;			if (range_usec < 0) {				range_sec--;				range_usec += 1000000;			}			range_dmsec = range_sec * 100 + range_usec/10000;#ifdef TEST			if (i > 0) {				diff = (qual->tstamp[i].tv_sec - 					qual->tstamp[i-1].tv_sec) * 1000000 -					qual->tstamp[i-1].tv_usec +					qual->tstamp[i].tv_usec;			}			fprintf(fd, "%lu.%lu %u (%lu)\n", range_sec, 				range_usec, qual->qual[i].qual, diff);#else			fprintf(fd, "%lu %u\n", range_dmsec, 				qual->qual[i].qual);#endif		} else if (info->output_type == 3) { /* timestamp, msec */			fprintf(fd, "%lu %u\n", qual->tstamp[i].tv_sec*1000+				qual->tstamp[i].tv_usec/1000 -				(start_time.tv_sec*1000-				 start_time.tv_usec/1000), 				qual->qual[i].qual);		} else if (info->output_type == 4) { /* timestamp, realtime,						        dmsec */			fprintf(fd, "%lu %u\n", qual->tstamp[i].tv_sec*100+				qual->tstamp[i].tv_usec/10000, 				qual->qual[i].qual);		} else if (info->output_type == 0) { /* plain quality */			fprintf(fd, "%d", qual->qual[i].qual);		} else {			fprintf(stderr, "Unknown output type! (%d)\n",				info->output_type);			fclose(fd);			return -1;		}				if (qual->current >= REC_NODE_CHUNK && 		    i >= (qual->current-1) && qual->next != NULL) {			qual = qual->next;			i = 0;			DEBUG(DEBUG_FLAG, "dump_fa: Next qual node\n");		} else			i++;	}		if (info->output_type > 0 && range_sec > 0) {		/* generate gnuplot header file */		snprintf(name, FILENAME_MAX, "FA-%s-dump.plot",			 inet_ntoa(rec->ip_addr));		header = fopen(name, "w");		if (!header) {			DEBUG(DEBUG_FLAG, "dump_fa: fopen: %s\n",			      strerror(errno));			fclose(fd);			return -1;		}		fprintf(header, "set output \"%s.gif\"\n", 			inet_ntoa(rec->ip_addr));		if (info->output_type == 1)			fprintf(header, "set terminal gif small size %d,%d\n"				"set xlabel \"Time t/s\"\n"				"set ylabel \"Quality\"\n"				"plot [0:%ld] [0:%d] 'FA-%s-dump.dat' title "				"\"FA (%s)\" with lines lt 3 \n",				IMG_X, IMG_Y, range_sec, Q_RANGE,				inet_ntoa(rec->ip_addr),				inet_ntoa(rec->ip_addr));		else if (info->output_type == 2)			fprintf(header, "set terminal gif small size %d,%d\n"				"set xlabel \"Time t/10msec\"\n"				"set ylabel \"Quality\"\n"				"plot [%ld:%ld] [0:%d] 'FA-%s-dump.dat' "				"title \"FA (%s)\" with lines lt 3 \n",				IMG_X, IMG_Y, start_time.tv_sec*100, 				start_time.tv_sec*100+range_sec*100, Q_RANGE,				inet_ntoa(rec->ip_addr),				inet_ntoa(rec->ip_addr));		else if (info->output_type == 3)			fprintf(header, "set terminal gif small size %d,%d\n"				"set xlabel \"Time t/ms\"\n"				"set ylabel \"Quality\"\n"				"plot [0:%ld] [0:%d] 'FA-%s-dump.dat' title "				"\"FA (%s)\" with lines lt 3 \n",				IMG_X, IMG_Y, range_sec*1000, Q_RANGE,				inet_ntoa(rec->ip_addr),				inet_ntoa(rec->ip_addr));		else if (info->output_type == 4)			fprintf(header, "set terminal gif small size %d,%d\n"				"set xlabel \"Time t/ms\"\n"				"set ylabel \"Quality\"\n"				"plot [%ld:%ld] [0:%d] 'FA-%s-dump.dat' title "				"\"FA (%s)\" with lines lt 3 \n",				IMG_X, IMG_Y, start_time.tv_sec*1000, 				start_time.tv_sec*1000+range_sec, Q_RANGE,				inet_ntoa(rec->ip_addr),				inet_ntoa(rec->ip_addr));		/* print entry into combined plot */		len = strlen(info->plot_str);		if (len + 100 < PLOT_STR_SIZE)			snprintf(&info->plot_str[len], 100, 				 "'FA-%s-dump.dat' title \"FA %s\" "				 "with lines, ", inet_ntoa(rec->ip_addr),				 inet_ntoa(rec->ip_addr));		fclose(header);	}	fclose(fd);	return 1;}int rec_dump(int type, int interval){	struct dump info;	char name[FILENAME_MAX];	long range;	int len;	FILE *header;	struct timeval stop_time;	DEBUG(DEBUG_FLAG, "rec_dump\n");	/* dump the data in specified format (type) */	if (rec_hash == NULL) {		DEBUG(DEBUG_FLAG, "rec_dump: hashtable NULL\n");		return -1;	}	memset(&info, 0, sizeof(info));	info.output_type = type;	info.interval = interval;	hashtable_iterator(rec_hash, dump_fa, &info);	len = strlen(info.plot_str);	if (len <= 0) {		DEBUG(DEBUG_FLAG, "rec_dump: info plot string < 0\n");		return 0;	}	/* Make special group gnuplot file */	snprintf(name, FILENAME_MAX, "group.plot");	header = fopen(name, "w");	if (header == NULL) {		DEBUG(DEBUG_FLAG, "rec_dump: fopen: %s\n",		      strerror(errno));		return -1;	}	gettimeofday(&stop_time, NULL);	range = stop_time.tv_sec - start_time.tv_sec;	fprintf(header, "set output \"group.gif\"\n"); 	if (type == 1)		fprintf(header, "set terminal gif large size %d,%d\n"			"set xlabel \"Time t/s\"\n"			"set ylabel \"Quality\"\n"			"plot [0:%ld] [0:%d] ", G_IMG_X, G_IMG_Y, range,			Q_RANGE);	else if (type == 2 || type == 4)		fprintf(header, "set terminal gif large size %d,%d\n"			"set xlabel \"Time t/10msec\"\n"			"set ylabel \"Quality\"\n"			"plot [0:%ld] [0:%d] ", G_IMG_X, G_IMG_Y, range*100,			Q_RANGE);		else if (type == 3)		fprintf(header, "set terminal gif large size %d,%d\n"			"set xlabel \"Time t/ms\"\n"			"set ylabel \"Quality\"\n"			"plot [0:%ld] [0:%d] ", G_IMG_X, G_IMG_Y, range*1000,			Q_RANGE);	info.plot_str[len - 2] = '\n';	info.plot_str[len - 1] = '\0';	fprintf(header, info.plot_str);	if (fclose(header))		DEBUG(DEBUG_FLAG, "rec_dump: fclose: %s\n", 		      strerror(errno));	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -