00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <errno.h>
00014 #include <string.h>
00015 #include <malloc.h>
00016 #include <assert.h>
00017 #include <asm/types.h>
00018 #include <sys/types.h>
00019 #include <sys/socket.h>
00020 #include <sys/ioctl.h>
00021 #include <linux/wireless.h>
00022 #include <linux/if_ether.h>
00023
00024 #include "dyn_wireless.h"
00025 #include "debug.h"
00026 #include "util.h"
00027
00028 #define DEBUG_FLAG '3'
00029
00030
00031 struct _spy_address {
00032 unsigned char hw[ETH_ALEN];
00033 int simulation_on;
00034 int *quals;
00035 int curr_buf;
00036 unsigned long *times;
00037
00038 int num;
00039 int curr;
00040 int full;
00041 int interval;
00042
00043 int scale;
00044
00045
00046 struct timeval last;
00047
00048 struct timeval start;
00049
00050 unsigned int passed;
00051
00052 unsigned int dropped;
00053
00054
00055 int sim_quals_buf0[MAX_NUM_QUALS];
00056 unsigned long sim_timestamps_buf0[MAX_NUM_QUALS];
00057 int num_of_quals_buf0;
00058 int sim_quals_buf1[MAX_NUM_QUALS];
00059 unsigned long sim_timestamps_buf1[MAX_NUM_QUALS];
00060 int num_of_quals_buf1;
00061 };
00062
00063
00064
00065 int dyn_wireless_create_socket(void)
00066 {
00067 int sock;
00068
00069 sock = socket(AF_INET, SOCK_DGRAM, 0);
00070 if (sock == -1)
00071 DEBUG(DEBUG_FLAG, "dyn_wireless_create_socket: %s\n",
00072 strerror(errno));
00073 return sock;
00074 }
00075
00076
00077 int dyn_wireless_get_ifname(const char *string, char *ifname)
00078 {
00079 int len = strlen(string);
00080 if (len < 0 || len > IFNAMSIZ)
00081 return 1;
00082
00083 memcpy(ifname, string, len+1);
00084 return 0;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 int dyn_wireless_iwspy_get(int sock, char *ifname, char *buffer)
00095 {
00096 struct iwreq wrq;
00097 int r;
00098
00099 assert(buffer != NULL);
00100 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00101 wrq.u.data.pointer = (caddr_t) buffer;
00102 wrq.u.data.length = 0;
00103 wrq.u.data.flags = 0;
00104 r = ioctl(sock, SIOCGIWSPY, &wrq);
00105 if (r < 0) {
00106 DEBUG(DEBUG_FLAG, "dyn_wireless_iwspy_get: Interface "
00107 "doesn't accept getting addresses.\n");
00108 DEBUG(DEBUG_FLAG, "\tSIOCGIWSPY: %s (%d)\n",
00109 strerror(errno), r);
00110 return -1;
00111 }
00112
00113 return (wrq.u.data.length);
00114 }
00115
00116
00117 int dyn_wireless_iwspy_set(int sock, char *ifname, char *buffer, int monitored)
00118 {
00119 struct iwreq wrq;
00120 int r;
00121
00122 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00123 wrq.u.data.pointer = (caddr_t) buffer;
00124 wrq.u.data.length = monitored;
00125 wrq.u.data.flags = 0;
00126 r = ioctl(sock, SIOCSIWSPY, &wrq);
00127 if (r < 0) {
00128 DEBUG(DEBUG_FLAG, "dyn_wireless_iwspy_set: Interface "
00129 "doesn't accept setting addresses.\n");
00130 DEBUG(DEBUG_FLAG, "\tSIOCSIWSPY: %s (%d)\n",
00131 strerror(errno), r);
00132 return -1;
00133 }
00134
00135 return 0;
00136 }
00137
00138
00139 int dyn_wireless_his_get(int sock, char *ifname, char *buffer)
00140 {
00141 struct iwreq wrq;
00142 int r;
00143
00144 assert(buffer != NULL);
00145 memset(&wrq, 0, sizeof(wrq));
00146 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00147 wrq.u.data.pointer = (caddr_t) buffer;
00148 wrq.u.data.length = 0;
00149 wrq.u.data.flags = 0;
00150 r = ioctl(sock, GET_HISTORY, &wrq);
00151 if (r < 0) {
00152 DEBUG(DEBUG_FLAG, "dyn_wireless_his_get: Interface "
00153 "doesn't accept getting history.\n");
00154 DEBUG(DEBUG_FLAG, "\tGET_HISTORY: %s (%d)\n",
00155 strerror(errno), r);
00156 return -1;
00157 }
00158
00159 return 0;
00160 }
00161
00162
00163 int dyn_wireless_his_set(int sock, char *ifname, char *range, int size)
00164 {
00165 struct iwreq wrq;
00166 int r;
00167
00168 memset(&wrq, 0, sizeof(wrq));
00169 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00170 wrq.u.data.pointer = (caddr_t) range;
00171 wrq.u.data.length = size;
00172 wrq.u.data.flags = 0;
00173 r = ioctl(sock, SET_HISTORY, &wrq);
00174 if (r < 0) {
00175 DEBUG(DEBUG_FLAG, "dyn_wireless_his_set: Interface "
00176 "doesn't accept setting history.\n");
00177 DEBUG(DEBUG_FLAG, "\tSET_HISTORY: %s (%d)\n",
00178 strerror(errno), r);
00179 return -1;
00180 }
00181
00182 return 0;
00183 }
00184
00185
00186
00187 struct quality_values *dyn_wireless_get_quals_node(struct quality_values *q)
00188 {
00189 struct quality_values *node;
00190
00191 node = (struct quality_values *)
00192 malloc(sizeof(struct quality_values));
00193 if (!node) {
00194 fprintf(stderr, "dyn_wireless_get_quals_node: memory "
00195 "allocation failed (%s)\n", strerror(errno));
00196 return NULL;
00197 }
00198 memset(node, 0, sizeof(struct quality_values));
00199
00200 if (q) {
00201 q->next = node;
00202 }
00203
00204 return node;
00205 }
00206
00207
00208
00209 int dyn_wireless_set_channel(int sock, char *ifname, int channel)
00210 {
00211 struct iwreq wrq;
00212 int r;
00213
00214 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00215 wrq.u.freq.m = channel;
00216 wrq.u.freq.e = 0;
00217 r = ioctl(sock, SIOCSIWFREQ, &wrq);
00218 if (r < 0) {
00219 DEBUG(DEBUG_FLAG, "dyn_wireless_set_channel: Interface "
00220 "doesn't accept setting channel. (%s, %d)\n",
00221 wrq.u.name, wrq.u.freq.m);
00222 DEBUG(DEBUG_FLAG, "\tSIOCSIWFREQ: %s (%d)\n",
00223 strerror(errno), r);
00224 return -1;
00225 }
00226
00227 return 0;
00228 }
00229
00230
00231
00232 int dyn_wireless_get_channel(int sock, char *ifname)
00233 {
00234 struct iwreq wrq;
00235 int r;
00236 unsigned int ch;
00237
00238 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00239 wrq.u.freq.m = 0;
00240 wrq.u.freq.e = 0;
00241 r = ioctl(sock, SIOCGIWFREQ, &wrq);
00242 if (r < 0) {
00243 DEBUG(DEBUG_FLAG, "dyn_wireless_get_channel: Interface "
00244 "doesn't accept reading the channel.\n");
00245 DEBUG(DEBUG_FLAG, "\tSIOCGIWFREQ: %s (%d)\n",
00246 strerror(errno), r);
00247 return -1;
00248 }
00249
00250 ch = (unsigned int)wrq.u.freq.m;
00251 if (ch > 14) {
00252
00253 switch (ch) {
00254 case 241200000:
00255 ch = 1;
00256 break;
00257 case 241700000:
00258 ch = 2;
00259 break;
00260 case 242200000:
00261 ch = 3;
00262 break;
00263 case 242700000:
00264 ch = 4;
00265 break;
00266 case 243200000:
00267 ch = 5;
00268 break;
00269 case 243700000:
00270 ch = 6;
00271 break;
00272 case 244200000:
00273 ch = 7;
00274 break;
00275 case 244700000:
00276 ch = 8;
00277 break;
00278 case 245200000:
00279 ch = 9;
00280 break;
00281 case 245700000:
00282 ch = 10;
00283 break;
00284 case 246200000:
00285 ch = 11;
00286 break;
00287 case 246700000:
00288 ch = 12;
00289 break;
00290 case 247200000:
00291 ch = 13;
00292 break;
00293 case 248400000:
00294 ch = 14;
00295 break;
00296 default:
00297 ch = -1;
00298 break;
00299 }
00300 }
00301
00302 return (int)ch;
00303 }
00304
00305
00306
00307 int dyn_wireless_get_name(int sock, char *ifname, char *name, int name_len)
00308 {
00309 struct iwreq wrq;
00310 int r, len;
00311
00312 if (name == NULL)
00313 return -1;
00314
00315 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00316 wrq.u.data.pointer = NULL;
00317 wrq.u.data.length = name_len;
00318 wrq.u.data.flags = 0;
00319 r = ioctl(sock, SIOCGIWNAME, &wrq);
00320 if (r < 0) {
00321 DEBUG(DEBUG_FLAG, "dyn_wireless_get_name: Interface "
00322 "doesn't accept reading name.\n");
00323 DEBUG(DEBUG_FLAG, "\tSIOCGIWNAME: %s (%d)\n",
00324 strerror(errno), r);
00325 return -1;
00326 }
00327
00328 len = strlen(wrq.u.name);
00329 len = len < name_len ? len : name_len;
00330 memcpy(name, wrq.u.name, len);
00331 DEBUG(DEBUG_FLAG, "dyn_wireless_get_name: \"%s\"\n", name);
00332
00333 return 0;
00334 }
00335
00336
00337
00338 int dyn_wireless_get_range(int sock, char *ifname, struct iw_range *range)
00339 {
00340 struct iwreq wrq;
00341 int r, len, max;
00342 char *buffer;
00343
00344 if (range == NULL)
00345 return -1;
00346
00347
00348
00349
00350
00351
00352
00353 len = sizeof(*range) + 256;
00354 buffer = (char *) malloc(len);
00355 if (buffer == NULL)
00356 return -1;
00357 memset(buffer, 0, len);
00358
00359 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00360 wrq.u.data.pointer = (caddr_t)buffer;
00361 wrq.u.data.length = sizeof(struct iw_range);
00362 wrq.u.data.flags = 0;
00363 r = ioctl(sock, SIOCGIWRANGE, &wrq);
00364 if (r < 0) {
00365 DEBUG(DEBUG_FLAG, "dyn_wireless_get_range: Interface "
00366 "doesn't accept getting range of parameters.\n");
00367 DEBUG(DEBUG_FLAG, "\tSIOCGIWRANGE: %s (%d)\n",
00368 strerror(errno), r);
00369 return -1;
00370 }
00371
00372 max = 0;
00373 for (r = sizeof(*range); r < len; r++)
00374 if (buffer[r] != 0)
00375 max = r;
00376 if (max > 0) {
00377 DEBUG(DEBUG_FLAG, "dyn_wireless_get_range: SIOCGIWRANGE "
00378 "overwrote buffer end with at least %i bytes!\n",
00379 max - sizeof(*range));
00380 }
00381
00382 memcpy(range, buffer, sizeof(*range));
00383 free(buffer);
00384 DEBUG(DEBUG_FLAG, "dyn_wireless_get_range: ok\n");
00385
00386 return 0;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 struct quality_values *dyn_wireless_get_simulator(int sock, char *ifname,
00412 char *hw)
00413 {
00414 struct quality_values *q;
00415 struct iwreq wrq;
00416 int r;
00417 struct _spy_address buffer;
00418 struct _spy_address *a;
00419
00420 a = &buffer;
00421 memcpy(a->hw, hw, ETH_ALEN);
00422 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00423 wrq.u.data.pointer = (caddr_t) &buffer;
00424 wrq.u.data.length = sizeof(struct _spy_address);
00425 wrq.u.data.flags = 0;
00426 r = ioctl(sock, GET_QUALITIES, &wrq);
00427 if (r < 0) {
00428 DEBUG(DEBUG_FLAG, "get_simulator: Interface "
00429 "doesn't accept getting simulated quality values.\n");
00430 DEBUG(DEBUG_FLAG, "\tSIOCDEVPRIVATE+0x4: %s (%d)\n",
00431 strerror(errno), r);
00432 return NULL;
00433 }
00434
00435 q = dyn_wireless_get_quals_node(NULL);
00436 if (q) {
00437 if (a->curr_buf == 1) {
00438 DEBUG(DEBUG_FLAG, "get_simulator: num=%d, curr=%d\n",
00439 a->num_of_quals_buf1, a->curr);
00440 memcpy((char *)&q->sim_quals,
00441 (char *)&a->sim_quals_buf1[a->curr],
00442 sizeof(int)*(a->num_of_quals_buf1 - a->curr));
00443 q->num_of_quals = a->num_of_quals_buf1 - a->curr;
00444 } else {
00445 DEBUG(DEBUG_FLAG, "get_simulator: num=%d, curr=%d\n",
00446 a->num_of_quals_buf0, a->curr);
00447 memcpy((char *)&q->sim_quals,
00448 (char *)&a->sim_quals_buf0[a->curr],
00449 sizeof(int)*(a->num_of_quals_buf0 - a->curr));
00450 q->num_of_quals = a->num_of_quals_buf0 - a->curr;
00451 }
00452 } else {
00453 DEBUG(DEBUG_FLAG, "get_simulator: Couldn't get quals node\n");
00454 return NULL;
00455 }
00456
00457 return (q);
00458 }
00459
00460
00461
00462 int dyn_wireless_set_simulator(int sock, char *ifname, char *hw,
00463 struct quality_values *q, int msec_ival,
00464 int scale)
00465 {
00466 struct iwreq wrq;
00467 int r;
00468 struct _spy_address buffer;
00469 struct _spy_address *a;
00470
00471 a = &buffer;
00472
00473 memcpy(a->hw, hw, ETH_ALEN);
00474 memcpy(a->sim_quals_buf0, q->sim_quals, sizeof(q->sim_quals));
00475 memcpy(a->sim_timestamps_buf0, q->sim_timestamps,
00476 sizeof(q->sim_timestamps));
00477 a->num_of_quals_buf0 = q->num_of_quals;
00478 a->interval = msec_ival;
00479 a->scale = scale;
00480 a->quals = NULL;
00481 a->times = NULL;
00482
00483 memcpy(wrq.u.name, ifname, IFNAMSIZ);
00484 wrq.u.data.pointer = (caddr_t) &buffer;
00485 wrq.u.data.length = sizeof(struct _spy_address);
00486 wrq.u.data.flags = 0;
00487 r = ioctl(sock, SET_QUALITIES, &wrq);
00488 if (r < 0) {
00489 DEBUG(DEBUG_FLAG, "set_simulator: Interface "
00490 "doesn't accept setting simulated quality values.\n");
00491 DEBUG(DEBUG_FLAG, "\tSIOCDEVPRIVATE+0x3: %s (%d)\n",
00492 strerror(errno), r);
00493 return -1;
00494 }
00495
00496 return 0;
00497 }
00498
00499
00500
00501 int dyn_wireless_check_simulator(int sock, char *ifname, char *hw)
00502 {
00503 struct iwreq wrq;
00504 int r;
00505
00506 memset(&wrq, 0, sizeof(wrq));
00507 memcpy(&wrq.u.name, ifname, IFNAMSIZ);
00508 wrq.u.data.pointer = (caddr_t)hw;
00509 wrq.u.data.length = ETH_ALEN;
00510 wrq.u.data.flags = 0;
00511 r = ioctl(sock, CHECK_QUALITIES, &wrq);
00512 if (r < 0) {
00513 DEBUG(DEBUG_FLAG, "check_simulator: Interface "
00514 "doesn't accept checking simulated quality values.\n");
00515 DEBUG(DEBUG_FLAG, "\tSIOCDEVPRIVATE+0x5: %s (%d)\n",
00516 strerror(errno), r);
00517 DEBUG(DEBUG_FLAG, "device: '%s', hw '%s'\n", ifname,
00518 ether_hwtoa((unsigned char *) hw));
00519 return -1;
00520 }
00521
00522 return r;
00523 }
00524
00525
00526
00527 int dyn_wireless_get_ap_address(int sock, const char *ifname, char *hw)
00528 {
00529 struct iwreq wrq;
00530
00531 assert(ifname != NULL && hw != NULL);
00532 memset(&wrq, 0, sizeof(wrq));
00533 memcpy(&wrq.u.name, ifname, IFNAMSIZ);
00534 if (ioctl(sock, SIOCGIWAP, &wrq) < 0) {
00535 DEBUG(DEBUG_FLAG, "dyn_wireless_get_ap_address: Interface '%s'"
00536 " does not accept SIOCGIWAP: %s\n", ifname,
00537 strerror(errno));
00538 return -1;
00539 }
00540
00541 memcpy(hw, wrq.u.ap_addr.sa_data, ETH_ALEN);
00542
00543 return 0;
00544 }