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

📄 dyn_wireless.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: dyn_wireless.c,v 1.17 2001/10/16 20:19:14 jm Exp $ * Dynamics wireless 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 <errno.h>#include <string.h>#include <malloc.h>#include <assert.h>#include <asm/types.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <linux/wireless.h>#include <linux/if_ether.h> /* ETH_ALEN */#include "dyn_wireless.h"#include "debug.h"#include "util.h"#define DEBUG_FLAG '3'struct _spy_address {		unsigned char hw[ETH_ALEN];   /* hw address */	int simulation_on;            /* simulator on for this hw */	int *quals;                   /* points to current quality buffer */	int curr_buf;  /* 0 (buf0) or 1 (buf1) */        unsigned long *times;	int num; 	int curr;                     /* last used quality value index */	int full;                     /* other buffer full? */	int interval;                 /* interval between quality values 					 in milli seconds */	int scale;                    /* timestamp scale: 0 = no timestamps,					 1 = in seconds, 2 = in tens of 					 milli seconds */	struct timeval last;          /* timestamp for last used quality 					 value */	struct timeval start;         /* timestamp when simulation started */	unsigned int passed;         /* how many packets passed on since last					drop (simulation on) */	unsigned int dropped;        /* how many packets dropped since last					pass on (simulation on) */	int sim_quals_buf0[MAX_NUM_QUALS]; /* quality values */	unsigned long sim_timestamps_buf0[MAX_NUM_QUALS]; 	int num_of_quals_buf0;        /* the number of quality values set */	int sim_quals_buf1[MAX_NUM_QUALS]; /* quality values */	unsigned long sim_timestamps_buf1[MAX_NUM_QUALS]; 	int num_of_quals_buf1;        /* the number of quality values set */};int dyn_wireless_create_socket(void){	int sock; 	sock = socket(AF_INET, SOCK_DGRAM, 0);	if (sock == -1)		DEBUG(DEBUG_FLAG, "dyn_wireless_create_socket: %s\n",		      strerror(errno));	return sock;}int dyn_wireless_get_ifname(const char *string, char *ifname){	int len = strlen(string);	if (len < 0 || len > IFNAMSIZ)		return 1;	memcpy(ifname, string, len+1);	return 0;}/* Get iwspy entries from the kernel. * return: *   the number of monitored entries on success *   -1 on failure (no wireless extensions?) * NOTE: Caller reserves memory for the buffer. */int dyn_wireless_iwspy_get(int sock, char *ifname, char *buffer){	struct iwreq wrq;	int r;	assert(buffer != NULL);	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t) buffer;	wrq.u.data.length  = 0;	wrq.u.data.flags   = 0;	r = ioctl(sock, SIOCGIWSPY, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_iwspy_get: Interface "		      "doesn't accept getting addresses.\n");		DEBUG(DEBUG_FLAG, "\tSIOCGIWSPY: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	return (wrq.u.data.length);}int dyn_wireless_iwspy_set(int sock, char *ifname, char *buffer, int monitored){	struct iwreq wrq;	int r;	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t) buffer;	wrq.u.data.length = monitored;	wrq.u.data.flags = 0;	r = ioctl(sock, SIOCSIWSPY, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_iwspy_set: Interface "		      "doesn't accept setting addresses.\n");		DEBUG(DEBUG_FLAG, "\tSIOCSIWSPY: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	return 0;}int dyn_wireless_his_get(int sock, char *ifname, char *buffer){	struct iwreq wrq;	int r;	assert(buffer != NULL);	memset(&wrq, 0, sizeof(wrq));	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t) buffer;	wrq.u.data.length = 0;	wrq.u.data.flags = 0;	r = ioctl(sock, GET_HISTORY, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_his_get: Interface "		      "doesn't accept getting history.\n");		DEBUG(DEBUG_FLAG, "\tGET_HISTORY: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	return 0;}int dyn_wireless_his_set(int sock, char *ifname, char *range, int size){	struct iwreq wrq;	int r;	memset(&wrq, 0, sizeof(wrq));	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t) range;	wrq.u.data.length = size;	wrq.u.data.flags = 0;	r = ioctl(sock, SET_HISTORY, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_his_set: Interface "		      "doesn't accept setting history.\n");		DEBUG(DEBUG_FLAG, "\tSET_HISTORY: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	return 0;}/* Get new quality values node */struct quality_values *dyn_wireless_get_quals_node(struct quality_values *q){	struct quality_values *node;		node = (struct quality_values *)		malloc(sizeof(struct quality_values));	if (!node) {		fprintf(stderr, "dyn_wireless_get_quals_node: memory "			"allocation failed (%s)\n", strerror(errno));		return NULL;	}	memset(node, 0, sizeof(struct quality_values));	if (q) {		q->next = node;	}	return node;}/* Set frequency/channel */int dyn_wireless_set_channel(int sock, char *ifname, int channel){	struct iwreq wrq;	int r;	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.freq.m = channel;	wrq.u.freq.e = 0;	r = ioctl(sock, SIOCSIWFREQ, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_set_channel: Interface "		      "doesn't accept setting channel. (%s, %d)\n",		      wrq.ifr_name, wrq.u.freq.m);		DEBUG(DEBUG_FLAG, "\tSIOCSIWFREQ: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	return 0;}/* Get frequency/channel */int dyn_wireless_get_channel(int sock, char *ifname){	struct iwreq wrq;	int r;	unsigned int ch;	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.freq.m = 0;	wrq.u.freq.e = 0;	r = ioctl(sock, SIOCGIWFREQ, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_get_channel: Interface "		      "doesn't accept reading the channel.\n");		DEBUG(DEBUG_FLAG, "\tSIOCGIWFREQ: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	ch = (unsigned int)wrq.u.freq.m;	if (ch > 14) {		/* change from frequency to channel */		switch (ch) {		case 241200000:			ch = 1;			break;		case 241700000:			ch = 2;			break;		case 242200000:			ch = 3;			break;		case 242700000:			ch = 4;			break;		case 243200000:			ch = 5;			break;		case 243700000:			ch = 6;			break;		case 244200000:			ch = 7;			break;		case 244700000:			ch = 8;			break;		case 245200000:			ch = 9;			break;		case 245700000:			ch = 10;			break;		case 246200000:			ch = 11;			break;		case 246700000:			ch = 12;			break;		case 247200000:			ch = 13;			break;		case 248400000:			ch = 14;			break;		default:			ch = -1;			break;		}	}	return (int)ch;}/* Get name of the wireless card */int dyn_wireless_get_name(int sock, char *ifname, char *name, int name_len){	struct iwreq wrq;	int r, len;		if (name == NULL)		return -1;		memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = NULL;	wrq.u.data.length  = name_len;	wrq.u.data.flags   = 0;	r = ioctl(sock, SIOCGIWNAME, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_get_name: Interface "		      "doesn't accept reading name.\n");		DEBUG(DEBUG_FLAG, "\tSIOCGIWNAME: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	len = strlen(wrq.u.name);	len = len < name_len ? len : name_len;	memcpy(name, wrq.u.name, len); 	DEBUG(DEBUG_FLAG, "dyn_wireless_get_name: \"%s\"\n", name);	return 0;}/* Get range of parameters */int dyn_wireless_get_range(int sock, char *ifname, struct iw_range *range){	struct iwreq wrq;	int r, len, max;	char *buffer;	if (range == NULL)		return -1;	/* At least iPAQ (i.e., Linux on ARM) seems to have some problems	 * in SIOCGIWRANGE.. It seems to write over the range buffer even	 * though length is set to match the buffer.. So, make a larger	 * temporary buffer to avoid breaking whatever data is after range	 * argument. */	len = sizeof(*range) + 256;	buffer = (char *) malloc(len);	if (buffer == NULL)		return -1;	memset(buffer, 0, len);	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t)buffer;	wrq.u.data.length  = sizeof(struct iw_range);	wrq.u.data.flags   = 0;	r = ioctl(sock, SIOCGIWRANGE, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_get_range: Interface "		      "doesn't accept getting range of parameters.\n");		DEBUG(DEBUG_FLAG, "\tSIOCGIWRANGE: %s (%d)\n", 		      strerror(errno), r);		return -1;	}	max = 0;	for (r = sizeof(*range); r < len; r++)		if (buffer[r] != 0)			max = r;	if (max > 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_get_range: SIOCGIWRANGE "		      "overwrote buffer end with at least %i bytes!\n",		      max - sizeof(*range));	}	memcpy(range, buffer, sizeof(*range));	free(buffer);	DEBUG(DEBUG_FLAG, "dyn_wireless_get_range: ok\n");	return 0;}/* Set desired station name *//* Get current station name *//* Get current network name (ESSID) *//* Set desired network name (ESSID) *//* Get current Access Point (BSSID) *//* Set the desired bitrate *//* Get the current bitrate *//* Set the desired RTS treshold *//* Get the current RTS treshold *//* Set the desired fragmentation treshold *//* Get the current fragmentation treshold *//* Set desired AP density *//* Get the current AP density *//**********************************//* Private ioctls for the testbed *//**********************************//* Get simulated values */struct quality_values *dyn_wireless_get_simulator(int sock, char *ifname, 						  char *hw){	struct quality_values *q;	struct iwreq wrq;	int r;	struct _spy_address buffer;	struct _spy_address *a;	a = &buffer;	memcpy(a->hw, hw, ETH_ALEN);	memcpy(wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t) &buffer;	wrq.u.data.length  = sizeof(struct _spy_address);	wrq.u.data.flags   = 0;	r = ioctl(sock, GET_QUALITIES, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "get_simulator: Interface "		      "doesn't accept getting simulated quality values.\n");		DEBUG(DEBUG_FLAG, "\tSIOCDEVPRIVATE+0x4: %s (%d)\n", 		      strerror(errno), r);		return NULL;	}		q = dyn_wireless_get_quals_node(NULL);	if (q) {		if (a->curr_buf == 1) {			DEBUG(DEBUG_FLAG, "get_simulator: num=%d, curr=%d\n",			      a->num_of_quals_buf1, a->curr);			memcpy((char *)&q->sim_quals, 			       (char *)&a->sim_quals_buf1[a->curr], 			       sizeof(int)*(a->num_of_quals_buf1 - a->curr));			q->num_of_quals = a->num_of_quals_buf1 - a->curr;		} else {			DEBUG(DEBUG_FLAG, "get_simulator: num=%d, curr=%d\n",			      a->num_of_quals_buf0, a->curr);			memcpy((char *)&q->sim_quals, 			       (char *)&a->sim_quals_buf0[a->curr], 			       sizeof(int)*(a->num_of_quals_buf0 - a->curr));			q->num_of_quals = a->num_of_quals_buf0 - a->curr;		}	} else {		DEBUG(DEBUG_FLAG, "get_simulator: Couldn't get quals node\n");		return NULL;	}	return (q);}/* Set simulated values */int dyn_wireless_set_simulator(int sock, char *ifname, char *hw, 			       struct quality_values *q, int msec_ival, 			       int scale){      struct iwreq wrq;      int r;      struct _spy_address buffer;      struct _spy_address *a;      a = &buffer;      /* copy attributes address */      memcpy(a->hw, hw, ETH_ALEN);      memcpy(a->sim_quals_buf0, q->sim_quals, sizeof(q->sim_quals));      memcpy(a->sim_timestamps_buf0, q->sim_timestamps, 	     sizeof(q->sim_timestamps));      a->num_of_quals_buf0 = q->num_of_quals;      a->interval = msec_ival;      a->scale = scale;      a->quals = NULL;      a->times = NULL;      memcpy(wrq.ifr_name, ifname, IFNAMSIZ);      wrq.u.data.pointer = (caddr_t) &buffer;      wrq.u.data.length  = sizeof(struct _spy_address);      wrq.u.data.flags   = 0;      r = ioctl(sock, SET_QUALITIES, &wrq);      if (r < 0) {              DEBUG(DEBUG_FLAG, "set_simulator: Interface "                    "doesn't accept setting simulated quality values.\n");              DEBUG(DEBUG_FLAG, "\tSIOCDEVPRIVATE+0x3: %s (%d)\n",                     strerror(errno), r);              return -1;      }      return 0;}/* Check if room for new chunk in simulator buffer */int dyn_wireless_check_simulator(int sock, char *ifname, char *hw) {	struct iwreq wrq;	int r;	memset(&wrq, 0, sizeof(wrq));	memcpy(&wrq.ifr_name, ifname, IFNAMSIZ);	wrq.u.data.pointer = (caddr_t)hw;	wrq.u.data.length  = ETH_ALEN;	wrq.u.data.flags   = 0;	r = ioctl(sock, CHECK_QUALITIES, &wrq);	if (r < 0) {		DEBUG(DEBUG_FLAG, "check_simulator: Interface "		      "doesn't accept checking simulated quality values.\n");		DEBUG(DEBUG_FLAG, "\tSIOCDEVPRIVATE+0x5: %s (%d)\n", 		      strerror(errno), r);		DEBUG(DEBUG_FLAG, "device: '%s', hw '%s'\n", ifname,		      ether_hwtoa((unsigned char *) hw));		return -1;	}	return r;}/* Get AP hw address */int dyn_wireless_get_ap_address(int sock, const char *ifname, char *hw){	struct iwreq wrq;	assert(ifname != NULL && hw != NULL);	memset(&wrq, 0, sizeof(wrq));	memcpy(&wrq.ifr_name, ifname, IFNAMSIZ);	if (ioctl(sock, SIOCGIWAP, &wrq) < 0) {		DEBUG(DEBUG_FLAG, "dyn_wireless_get_ap_address: Interface '%s'"		      " does not accept SIOCGIWAP: %s\n", ifname,		      strerror(errno));		return -1;	}	memcpy(hw, wrq.u.ap_addr.sa_data, ETH_ALEN);	return 0;}

⌨️ 快捷键说明

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