dyn_wireless.c

Go to the documentation of this file.
00001 /* $Id: dyn_wireless.c,v 1.17 2001/10/16 20:19:14 jm Exp $
00002  * Dynamics wireless module
00003  *
00004  * Dynamic hierarchial IP tunnel
00005  * Copyright (C) 1998-2000, Dynamics group
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation. See README and COPYING for
00010  * more details.
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> /* ETH_ALEN */
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];   /* hw address */
00033         int simulation_on;            /* simulator on for this hw */
00034         int *quals;                   /* points to current quality buffer */
00035         int curr_buf;  /* 0 (buf0) or 1 (buf1) */
00036         unsigned long *times;
00037 
00038         int num; 
00039         int curr;                     /* last used quality value index */
00040         int full;                     /* other buffer full? */
00041         int interval;                 /* interval between quality values 
00042                                          in milli seconds */
00043         int scale;                    /* timestamp scale: 0 = no timestamps,
00044                                          1 = in seconds, 2 = in tens of 
00045                                          milli seconds */
00046         struct timeval last;          /* timestamp for last used quality 
00047                                          value */
00048         struct timeval start;         /* timestamp when simulation started */
00049 
00050         unsigned int passed;         /* how many packets passed on since last
00051                                         drop (simulation on) */
00052         unsigned int dropped;        /* how many packets dropped since last
00053                                         pass on (simulation on) */
00054 
00055         int sim_quals_buf0[MAX_NUM_QUALS]; /* quality values */
00056         unsigned long sim_timestamps_buf0[MAX_NUM_QUALS]; 
00057         int num_of_quals_buf0;        /* the number of quality values set */
00058         int sim_quals_buf1[MAX_NUM_QUALS]; /* quality values */
00059         unsigned long sim_timestamps_buf1[MAX_NUM_QUALS]; 
00060         int num_of_quals_buf1;        /* the number of quality values set */
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 /* Get iwspy entries from the kernel.
00089  * return:
00090  *   the number of monitored entries on success
00091  *   -1 on failure (no wireless extensions?)
00092  * NOTE: Caller reserves memory for the buffer.
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 /* Get new quality values node */
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 /* Set frequency/channel */
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 /* Get frequency/channel */
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                 /* change from frequency to channel */
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 /* Get name of the wireless card */
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 /* Get range of parameters */
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         /* At least iPAQ (i.e., Linux on ARM) seems to have some problems
00348          * in SIOCGIWRANGE.. It seems to write over the range buffer even
00349          * though length is set to match the buffer.. So, make a larger
00350          * temporary buffer to avoid breaking whatever data is after range
00351          * argument. */
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 /* Set desired station name */
00391 /* Get current station name */
00392 /* Get current network name (ESSID) */
00393 /* Set desired network name (ESSID) */
00394 /* Get current Access Point (BSSID) */
00395 /* Set the desired bitrate */
00396 /* Get the current bitrate */
00397 /* Set the desired RTS treshold */
00398 /* Get the current RTS treshold */
00399 /* Set the desired fragmentation treshold */
00400 /* Get the current fragmentation treshold */
00401 /* Set desired AP density */
00402 /* Get the current AP density */
00403 
00404 
00405 /**********************************/
00406 /* Private ioctls for the testbed */
00407 /**********************************/
00408 
00409 
00410 /* Get simulated values */
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 /* Set simulated values */
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       /* copy attributes address */
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 /* Check if room for new chunk in simulator buffer */
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 /* Get AP hw address */
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 }

Generated on Tue Jan 15 08:50:43 2008 for Virtual foreign agent generator version 0.1 by  doxygen 1.5.1