/* AP Radar * June 2002 * donald.g.park@iname.com * * This method comes from iwlist.c in the wireless-tools package * * Released under the MIT Open Source Licence * http://www.opensource.org/licenses/mit-license.php */ #include #include #include #include "AccessPoint.h" #include "AccessPointList.h" AccessPointList * print_scanning_info (int skfd, const char *ifname_const) { AccessPointList *aplist; aplist = new AccessPointList; // AP Radar will compile under wireless extensions of 13 or // less, but it wont be able to scan for APs #if WIRELESS_EXT > 13 struct iwreq wrq; unsigned char buffer[IW_SCAN_MAX_DATA]; /* Results */ struct timeval tv; /* Select timeout */ int timeout = 5000000; /* 5s */ char *ifname = (char *) ifname_const; /* Init timeout value -> 250ms */ tv.tv_sec = 0; tv.tv_usec = 250000; /* * Here we should look at the command line args and set the IW_SCAN_ flags * properly */ wrq.u.param.flags = IW_SCAN_DEFAULT; wrq.u.param.value = 0; /* Later */ /* Initiate Scanning */ if (iw_set_ext (skfd, ifname, SIOCSIWSCAN, &wrq) < 0) { if (errno != EPERM) { fprintf (stderr, "%-8.8s Interface doesn't support scanning : %s\n\n", ifname, strerror (errno)); return (0); } /* If we don't have the permission to initiate the scan, we may * still have permission to read left-over results. * But, don't wait !!! */ tv.tv_usec = 0; } //cout << "AP Scan requested. going into select loop" << endl; timeout -= tv.tv_usec; /* Forever */ while (1) { fd_set rfds; /* File descriptors for select */ int last_fd; /* Last fd */ int ret; /* Guess what ? We must re-generate rfds each time */ FD_ZERO (&rfds); last_fd = -1; /* In here, add the rtnetlink fd in the list */ /* Wait until something happens */ ret = select (last_fd + 1, &rfds, NULL, NULL, &tv); /* Check if there was an error */ if (ret < 0) { if (errno == EAGAIN || errno == EINTR) continue; fprintf (stderr, "Unhandled signal - exiting...\n"); return (0); } /* Check if there was a timeout */ if (ret == 0) { /* Try to read the results */ wrq.u.data.pointer = (char *) buffer; wrq.u.data.flags = 0; wrq.u.data.length = sizeof (buffer); if (iw_get_ext (skfd, ifname, SIOCGIWSCAN, &wrq) < 0) { /* Check if results not available yet */ if (errno == EAGAIN) { /* Restart timer for only 100ms */ tv.tv_sec = 0; tv.tv_usec = 100000; timeout -= tv.tv_usec; if (timeout > 0) continue; /* Try again later */ } /* Bad error */ fprintf (stderr, "%-8.8s Failed to read scan data : %s\n\n", ifname, strerror (errno)); return (aplist); } else /* We have the results, go to process them */ break; } /* In here, check if event and event type * if scan event, read results. All errors bad & no reset timeout */ } if (wrq.u.data.length) { struct iw_event iwe; struct stream_descr stream; int ap_num = 1; int ret; struct iw_range range; int has_range; int we_version = iw_get_kernel_we_version(); has_range = (iw_get_range_info (skfd, ifname, &range) >= 0); printf ("%-8.8s Scan completed :\n", ifname); iw_init_event_stream (&stream, (char *) buffer, wrq.u.data.length); // loop through all the AP information // how do I associate an event with an AP? do { /* Extract an event and print it */ /* iwlib 27 added the extra int on the end */ ret = iw_extract_event_stream (&stream, &iwe, we_version); /* iwlib pre-27 users use this line ret = iw_extract_event_stream (&stream, &iwe); */ if (ret > 0) { /* Now, let's decode the event */ switch (iwe.cmd) { case SIOCGIWAP: // Allocate a new AP structure AccessPoint * newap; newap = new AccessPoint; aplist->push_back (newap); //cout << " NEW AP from accesspoint scan" << endl; newap->setBssid (iwe.u.ap_addr.sa_data); break; case SIOCGIWMODE: //printf(" Mode:%s %d\n", // iw_operation_mode[iwe.u.mode], iwe.u.mode); // int32 mode. 1 = ad-hoc newap->setMode (iwe.u.mode); break; case SIOCGIWESSID: char essid[IW_ESSID_MAX_SIZE + 1]; if ((iwe.u.essid.pointer) && (iwe.u.essid.length)) memcpy (essid, iwe.u.essid.pointer, iwe.u.essid.length); //printf("essid.length %d", iwe.u.essid.length); essid[iwe.u.essid.length] = '\0'; if (iwe.u.essid.flags) { /* Does it have an ESSID index ? */ if ((iwe.u.essid.flags & IW_ENCODE_INDEX) > 1) { //printf(" ESSID:\"%s\" [%d]\n", essid, // (iwe.u.essid.flags & IW_ENCODE_INDEX)); } else { //printf(" ESSID:\"%s\"\n", essid); //awin->add_button(essid); newap->setEssid (new string (essid)); } } else { //printf(" ESSID:off/any\n"); } break; case SIOCGIWENCODE: unsigned char key[IW_ENCODING_TOKEN_MAX]; if (iwe.u.data.pointer) memcpy (key, iwe.u.essid.pointer, iwe.u.data.length); else iwe.u.data.flags |= IW_ENCODE_NOKEY; //printf(" Encryption key:"); if (iwe.u.data.flags & IW_ENCODE_DISABLED) { //printf("off\n"); newap->setWEP (0); } else { newap->setWEP (1); } break; case SIOCGIWFREQ: double freq; /* Frequency/channel */ freq = iw_freq2float(&iwe.u.freq); //printf(" %s\n", buffer); newap->setFrequency (freq); break; case SIOCGIWRATE: //double rate = iwe.u.bitrate.value; //printf(" Bit Rate:%d\n", iwe.u.bitrate.value); break; case IWEVQUAL: /* Not that reliable, disable */ iwe.u.qual.updated = 0x0; if (has_range && (iwe.u.qual.level != 0)) { /* If the statistics are in dBm */ if (iwe.u.qual.level > range.max_qual.level) { /* Statistics are in dBm (absolute power measurement) */ int quality = iwe.u.qual.level - 0x100; //printf(" quality: %d\n", quality); newap->setSignalStrength (quality); } } break; #if WIRELESS_EXT >= 15 case IWEVCUSTOM: char custom[IW_CUSTOM_MAX+1]; if((iwe.u.data.pointer) && (iwe.u.data.length)) memcpy(custom, iwe.u.data.pointer, iwe.u.data.length); custom[iwe.u.data.length] = '\0'; printf(" Extra:%s\n", custom); break; #endif default: printf (" (Unknown Wireless Token 0x%04X)\n", iwe.cmd); break; } // switch(iwe.cmd) } // if(ret>0) else printf ("%-8.8s No scan results\n", ifname); } while(ret>0); // do printf ("\n"); #else #warning Kernel version doesnt support wireless scanning printf ("AP Radar compiled without scanning capabilites.\n"); #endif return (aplist); } // if (wrq.u. } /* * Copyright (c) 2002 Donald G. Park * The MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */