📄 dyn_wireless.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 + -