/* This file is part of Kismet Kismet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kismet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Kismet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #if defined(HAVE_LIBPCAP) && defined(HAVE_LIBAIRPCAP) && defined(SYS_CYGWIN) #include "airpcapsource.h" // Prototypes of Windows-specific pcap functions. // wpcap.dll contains these functions, but they are not exported to cygwin because // cygwin doesn't "officially" support the Windows extensions. These functions, // however, are safe to use. extern "C" PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); extern "C" HANDLE pcap_getevent (pcap_t *p); extern "C" int pcap_setmintocopy (pcap_t *p, int size); int AirPcapSource::OpenSource() { channel = 0; errstr[0] = '\0'; char *unconst = strdup(interface.c_str()); pd = pcap_open_live(unconst, MAX_PACKET_LEN, 1, -1, errstr); free(unconst); if (strlen(errstr) > 0) return -1; paused = 0; errstr[0] = '\0'; // Gather the data link if (DatalinkType() < 0) { snprintf(errstr, 1024, "unable to get the data link on %s", interface.c_str()); pcap_close(pd); return -1; } // Fetch the airpcap channel if ((airpcap_handle = pcap_get_airpcap_handle(pd)) == NULL) { snprintf(errstr, 1024, "Adapter %s does not have wireless extensions", interface.c_str()); pcap_close(pd); return -1; } // Set the link mode to give us radiotap headers // Removed - no deterministic method to set radiotap mode on airpcap. By // default the drivers ought to be in rtap mode, if they're not we'll // figure it out from the link type later but can't try to set the mode. #if 0 if (!AirpcapSetLinkType(airpcap_handle, AIRPCAP_LT_802_11_PLUS_RADIO)) { snprintf(errstr, 1024, "Adapter %s failed setting radiotap link layer: %s", interface.c_str(), AirpcapGetLastError(airpcap_handle)); pcap_close(pd); return -1; } #endif // Tell the AirPcap adapter that we want the correct frames only // (XXX Is this needed?) // (XXX It doesn't hurt. Kismet doesn't do anything but validate FCS itself // and throw them out, so we might as well toss them out at the // airpcap level - dragorn) if (!AirpcapSetFcsValidation(airpcap_handle, AIRPCAP_VT_ACCEPT_CORRECT_FRAMES)) { snprintf(errstr, 1024, "Adapter %s failed setting radiotap link layer: %s", interface.c_str(), AirpcapGetLastError(airpcap_handle)); pcap_close(pd); return -1; } // Add it to our local copy of the fd event mangler fd_mangle.AddHandle(pcap_getevent(pd)); fd_mangle.Activate(); return 0; } int AirPcapSource::FetchPacket(kis_packet *packet, uint8_t *data, uint8_t *moddata) { int ret; if ((ret = PcapSource::FetchPacket(packet, data, moddata)) == 0) { fd_mangle.Reset(); fd_mangle.Signalread(); } return ret; } #if 0 int AirPcapSource::FetchChannel() { unsigned int ch; if (!AirpcapGetDeviceChannel(airpcap_handle, &ch)) return -1; return (int) ch; } #endif int AirPcapSource::FetchDescriptor() { // Fall through to our HANDLE to FD mangler return fd_mangle.GetFd(); } int AirPcapSource::SetChannel(unsigned int in_ch, char *in_err) { if (!AirpcapSetDeviceChannel(airpcap_handle, in_ch)) { snprintf(in_err, 1024, "Adapter %s failed setting channel: %s", interface.c_str(), AirpcapGetLastError(airpcap_handle)); return -1; } return 0; } int AirPcapSource::FetchSignalLevels(int *in_siglev, int *in_noiselev) { *in_siglev = 0; *in_noiselev = 0; return 0; } KisPacketSource *airpcapsource_registrant(string in_name, string in_device, char *in_err) { return new AirPcapSource(in_name, in_device); } // Spawn an airpcap device and get the info from the user KisPacketSource *airpcapsourceq_registrant(string in_name, string in_device, char *in_err) { pcap_if_t *alldevs, *d; int i; int intnum; AirPcapSource *src = NULL; char errbuf[1024]; if (pcap_findalldevs(&alldevs, errbuf) == -1) { snprintf(in_err, 1024, "Error in pcap_findalldevs: %s\n", errbuf); return NULL; } fprintf(stdout, "Available interfaces:\n"); for (d = alldevs, i = 0; d != NULL; d = d->next) { fprintf(stdout, "%d. %s\n", ++i, d->name); if (d->description) fprintf(stdout, " %s\n", d->description); else fprintf(stdout, " No description available\n"); } if (i == 0) { pcap_freealldevs(alldevs); snprintf(in_err, 1024, "No interfaces found, are WinPcap and AirPcap " "installed and the AirPcap device attached?"); return NULL; } while (1) { fprintf(stdout, "Enter interface number (1-%d):", i); if (fscanf(stdin, "%d", &intnum) != 1) { fprintf(stdout, "Invalid entry\n"); continue; } if (intnum < 1 || intnum > i) { fprintf(stdout, "Invalid entry, must be between 1 and %d\n", i); continue; } break; } // Find the adapter for (d = alldevs, i = 0; i < intnum - 1; d = d->next, i++) ; src = new AirPcapSource(in_name, string(d->name)); pcap_freealldevs(alldevs); return src; } int chancontrol_airpcap(const char *in_dev, int in_ch, char *in_err, void *in_ext) { // Channel control uses the external pointer return ((AirPcapSource *) in_ext)->SetChannel(in_ch, in_err); } #endif