From 435e7c610645766cad5f22034f000855ef2c3f15 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 31 Jul 2014 17:29:36 -0700 Subject: Move the AirPcap stuff into caputils. Change-Id: I64b45dad36a3ec491aeb9de3439b4fe19b46f9d8 Reviewed-on: https://code.wireshark.org/review/3308 Reviewed-by: Guy Harris --- caputils/CMakeLists.txt | 1 + caputils/Makefile.common | 3 + caputils/airpcap.h | 921 ++++++++++++++++ caputils/airpcap_loader.c | 2552 +++++++++++++++++++++++++++++++++++++++++++++ caputils/airpcap_loader.h | 560 ++++++++++ 5 files changed, 4037 insertions(+) create mode 100644 caputils/airpcap.h create mode 100644 caputils/airpcap_loader.c create mode 100644 caputils/airpcap_loader.h (limited to 'caputils') diff --git a/caputils/CMakeLists.txt b/caputils/CMakeLists.txt index a12d09f15d..0d9364f2ad 100644 --- a/caputils/CMakeLists.txt +++ b/caputils/CMakeLists.txt @@ -36,6 +36,7 @@ endif() set(CAPUTILS_SRC ${PLATFORM_CAPUTILS_SRC} + airpcap_loader.c capture-pcap-util.c iface_monitor.c ws80211_utils.c diff --git a/caputils/Makefile.common b/caputils/Makefile.common index f09079d9e7..75544e757e 100644 --- a/caputils/Makefile.common +++ b/caputils/Makefile.common @@ -23,11 +23,14 @@ CAPUTILS_SRC = \ $(PLATFORM_CAPUTILS_SRC) \ + airpcap_loader.c \ capture-pcap-util.c \ iface_monitor.c \ ws80211_utils.c noinst_HEADERS = \ + airpcap.h \ + airpcap_loader.h \ capture_ifinfo.h \ capture-pcap-util.h \ capture-pcap-util-int.h \ diff --git a/caputils/airpcap.h b/caputils/airpcap.h new file mode 100644 index 0000000000..035df2461f --- /dev/null +++ b/caputils/airpcap.h @@ -0,0 +1,921 @@ +/* + * Copyright (c) 2006-2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if !defined(AIRPCAP_H__EAE405F5_0171_9592_B3C2_C19EC426AD34__INCLUDED_) +#define AIRPCAP_H__EAE405F5_0171_9592_B3C2_C19EC426AD34__INCLUDED_ + +#ifdef _MSC_VER +/* This disables a VS warning for zero-sized arrays. */ +#pragma warning( disable : 4200) +/* This stops VS2005 ranting against stdio. */ +#pragma warning( disable : 4996) +#endif + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + \mainpage AirPcap interface documentation + + \section Introduction + + This document describes the data structures and the functions exported by the CACE Technologies AirPcap library. + The AirPcap library provides low-level access to the AirPcap driver including advanced capabilities such as channel setting, + link type control and WEP configuration.
+ This manual includes the following sections: + + \note throughout this documentation, \e device refers to a physical USB AirPcap device, while \e adapter is an open API + instance. Most of the AirPcap API operations are adapter-specific but some of them, like setting the channel, are + per-device and will be reflected on all the open adapters. These functions will have "Device" in their name, e.g. + AirpcapSetDeviceChannel(). + + \b Sections: + + - \ref airpcapfuncs + - \ref airpcapdefs + - \ref radiotap +*/ + +/** @defgroup airpcapdefs AirPcap definitions and data structures + * @{ + */ + +/*! + \brief This string is the fixed prefix in the airpcap adapter name. + It can be used to parse the name field in an AirpcapDeviceDescription structure. +*/ +#define AIRPCAP_DEVICE_NAME_PREFIX "\\\\.\\airpcap" + +/*! + \brief This string is the scanf modifier to extract the adapter number from an adapter name. + It can be used to parse the name field in an AirpcapDeviceDescription structure with scanf. +*/ +#define AIRPCAP_DEVICE_NUMBER_EXTRACT_STRING "\\\\.\\airpcap%u" + +#define AIRPCAP_DEVICE_ANY_EXTRACT_STRING "\\\\.\\airpcap_any" + +/*! + \brief Entry in the list returned by \ref AirpcapGetDeviceList(); +*/ +typedef struct _AirpcapDeviceDescription +{ + struct _AirpcapDeviceDescription *next; /* < Next element in the list */ + gchar * Name; /* < Device name */ + gchar * Description; /* < Device description */ +} AirpcapDeviceDescription, *PAirpcapDeviceDescription; + +#define MAX_ENCRYPTION_KEYS 64 + +#define WEP_KEY_MAX_SIZE 32 /* < Maximum size of a WEP key, in bytes. This is the size of an entry in the + < AirpcapWepKeysCollection structure. */ + +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma pack(push) +#pragma pack(1) +#endif +#endif + +#define AIRPCAP_KEYTYPE_WEP 0 /* < Key type: WEP. The key can have an arbitrary length smaller than 32 bytes. */ +#define AIRPCAP_KEYTYPE_TKIP 1 /* < Key type: TKIP (WPA). NOT SUPPORTED YET. */ +#define AIRPCAP_KEYTYPE_CCMP 2 /* < Key type: CCMP (WPA2). NOT SUPPORTED YET. */ + +/*! + \brief WEP key container +*/ +typedef struct _AirpcapKey +{ + guint KeyType; /* < Type of key, can be on of: \ref AIRPCAP_KEYTYPE_WEP, \ref AIRPCAP_KEYTYPE_TKIP, \ref AIRPCAP_KEYTYPE_CCMP. Only AIRPCAP_KEYTYPE_WEP is supported by the driver at the moment. */ + guint KeyLen; /* < Length of the key, in bytes */ + guint8 KeyData[WEP_KEY_MAX_SIZE]; /* < Key Data */ +} +#ifdef __MINGW32__ +__attribute__((__packed__)) +#endif +AirpcapKey, *PAirpcapKey; + +/*! + \brief frequency Band. + 802.11 adapters can support different frequency bands, the most important of which are: 2.4GHz (802.11b/g/n) + and 5GHz (802.11a/n). +*/ +typedef enum _AirpcapChannelBand +{ + AIRPCAP_CB_AUTO = 1, /* < Automatically pick the best frequency band */ + AIRPCAP_CB_2_4_GHZ = 2, /* < 2.4 GHz frequency band */ + AIRPCAP_CB_4_GHZ = 4, /* < 4 GHz frequency band */ + AIRPCAP_CB_5_GHZ = 5 /* < 5 GHz frequency band */ +}AirpcapChannelBand, *PAirpcapChannelBand; + +/*! + \brief Type of frame validation the adapter performs. + An adapter can be instructed to accept different kind of frames: correct frames only, frames with wrong Frame Check Sequence (FCS) only, all frames. +*/ +typedef enum _AirpcapValidationType +{ + AIRPCAP_VT_ACCEPT_EVERYTHING = 1, /* < Accept all the frames the device captures */ + AIRPCAP_VT_ACCEPT_CORRECT_FRAMES = 2, /* < Accept correct frames only, i.e. frames with correct Frame Check Sequence (FCS). */ + AIRPCAP_VT_ACCEPT_CORRUPT_FRAMES = 3, /* < Accept corrupt frames only, i.e. frames with wrong Frame Check Sequence (FCS). */ + AIRPCAP_VT_UNKNOWN = 4 /* < Unknown validation type. You should see it only in case of error. */ +}AirpcapValidationType, *PAirpcapValidationType; + +/*! + \brief Type of decryption the adapter performs. + An adapter can be instructed to turn decryption (based on the device-configured keys configured + with \ref AirpcapSetDeviceKeys()) on or off. +*/ +typedef enum _AirpcapDecryptionState +{ + AIRPCAP_DECRYPTION_ON = 1, /* < This adapter performs decryption */ + AIRPCAP_DECRYPTION_OFF = 2 /* < This adapter does not perform decryption */ +}AirpcapDecryptionState, *PAirpcapDecryptionState; + + +/*! + \brief Storage for a MAC address +*/ +typedef struct _AirpcapMacAddress +{ + guint8 Address[6]; /* < MAC address bytes */ +} +#ifdef __MINGW32__ +__attribute__((__packed__)) +#endif +AirpcapMacAddress, *PAirpcapMacAddress; + +/*! + \brief This structure is used to store a collection of WEP keys. + Note that the definition of the structure has one key in it + (so that this code can be compiled by compilers that don't + support zero-length arrays), so be careful to allocate a buffer + with the size of the set of keys, as per the following example: + + \code + PAirpcapKeysCollection KeysCollection; + guint KeysCollectionSize; + + KeysCollectionSize = AirpcapKeysCollectionSize(NumKeys); + + KeysCollection = (PAirpcapKeysCollection)malloc(KeysCollectionSize); + if(!KeysCollection) + { + Error + } + \endcode +*/ +typedef struct _AirpcapKeysCollection +{ + guint nKeys; /* < Number of keys in the collection */ + AirpcapKey Keys[1]; /* < Array of nKeys keys. */ +} AirpcapKeysCollection, *PAirpcapKeysCollection; + +#define AirpcapKeysCollectionSize(nKeys) \ + ((sizeof(AirpcapKeysCollection) - sizeof(AirpcapKey)) + ((nKeys) * sizeof(AirpcapKey))) +#define AirpcapKeysCollectionSizeToKeyCount(size) \ + (guint)(((size) - AirpcapKeysCollectionSize(0))/sizeof(AirpcapKey)) + +/*! + \brief Packet header. + + This structure defines the BPF that precedes every packet delivered to the application. +*/ +typedef struct _AirpcapBpfHeader +{ + guint TsSec; /* < Timestamp associated with the captured packet. SECONDS. */ + guint TsUsec; /* < Timestamp associated with the captured packet. MICROSECONDS. */ + guint Caplen; /* < Length of captured portion. The captured portion can be different from the original packet, because it is possible (with a proper filter) to instruct the driver to capture only a portion of the packets. */ + guint Originallen; /* < Original length of packet */ + guint16 Hdrlen; /* < Length of bpf header (this struct plus alignment padding). In some cases, a padding could be added between the end of this structure and the packet data for performance reasons. This field can be used to retrieve the actual data of the packet. */ +} +#ifdef __MINGW32__ +__attribute__((__packed__)) +#endif +AirpcapBpfHeader, *PAirpcapBpfHeader; + +/* Helper macros to extract packets coming from the driver. Rounds up to the next even multiple of AIRPCAP_ALIGNMENT. */ +#define AIRPCAP_ALIGNMENT sizeof(int) +#define AIRPCAP_WORDALIGN(x) (((x)+(AIRPCAP_ALIGNMENT-1))&~(AIRPCAP_ALIGNMENT-1)) + +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma pack(pop) +#endif +#endif + +#define AIRPCAP_ERRBUF_SIZE 512 /* < Size of the error buffer, in bytes */ + +#ifndef __AIRPCAP_DRIVER__ + +/*! + \brief Link type. + AirPcap supports two kind of 802.11 linktypes: plain 802.11 and radiotap. +*/ +#undef _AirpcapLinkType +typedef enum _AirpcapLinkType +{ + AIRPCAP_LT_802_11 = 1, /* < plain 802.11 linktype. Every packet in the buffer contains the raw 802.11 frame, including MAC FCS. */ + AIRPCAP_LT_802_11_PLUS_RADIO = 2, /* < 802.11 plus radiotap linktype. Every packet in the buffer contains a radiotap header followed by the 802.11 frame. MAC FCS is included. */ + AIRPCAP_LT_UNKNOWN = 3, /* < Unknown linktype. You should see it only in case of error. */ + AIRPCAP_LT_802_11_PLUS_PPI = 4 /* < 802.11 plus PPI header linktype. Every packet in the buffer contains a PPI header followed by the 802.11 frame. MAC FCS is included. */ +}AirpcapLinkType, *PAirpcapLinkType; + +#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) +#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ +/*! + \brief Adapter handle. +*/ +typedef struct _AirpcapHandle AirpcapHandle, *PAirpcapHandle; +#endif + +/*! + \brief Capture statistics. + Returned by \ref AirpcapGetStats(); +*/ +typedef struct _AirpcapStats +{ + guint Recvs; /* < Number of packets that the driver received by the adapter */ + /* < from the beginning of the current capture. This value includes the packets */ + /* < dropped because of buffer full. */ + guint Drops; /* < number of packets that the driver dropped from the beginning of a capture. */ + /* < A packet is lost when the the buffer of the driver is full. */ + guint IfDrops; /* < Packets dropped by the card before going to the USB bus. */ + /* < Not supported at the moment. */ + guint Capt; /* < number of packets that pass the BPF filter, find place in the kernel buffer and */ + /* < therefore reach the application. */ +}AirpcapStats, *PAirpcapStats; + +/*! + \brief Channel information. + Used by \ref AirpcapSetDeviceChannelEx(), \ref AirpcapGetDeviceChannelEx(), \ref AirpcapGetDeviceSupportedChannels() +*/ +typedef struct _AirpcapChannelInfo +{ + guint Frequency; /* < Channel frequency, in MHz. */ + /*! + \brief 802.11n specific. Offset of the extension channel in case of 40MHz channels. + + Possible values are -1, 0 +1: + - -1 means that the extension channel should be below the control channel (e.g. Control = 5 and Extension = 1) + - 0 means that no extension channel should be used (20MHz channels or legacy mode) + - +1 means that the extension channel should be above the control channel (e.g. Control = 1 and Extension = 5) + + In case of 802.11a/b/g channels (802.11n legacy mode), this field should be set to 0. + */ + gchar ExtChannel; + guint8 Reserved[3]; /* < Reserved. It should be set to {0,0,0}. */ +} + AirpcapChannelInfo, *PAirpcapChannelInfo; + + +/*@}*/ + +/** @defgroup airpcapfuncs AirPcap functions + * @{ + */ + +/*! + \brief Return a string with the API version + \param VersionMajor Pointer to a variable that will be filled with the major version number. + \param VersionMinor Pointer to a variable that will be filled with the minor version number. + \param VersionRev Pointer to a variable that will be filled with the revision number. + \param VersionBuild Pointer to a variable that will be filled with the build number. +*/ +void AirpcapGetVersion(guint * VersionMajor, guint * VersionMinor, guint * VersionRev, guint * VersionBuild); + +/*! + \brief Return the last error related to the specified handle + \param AdapterHandle Handle to an open adapter. + \return The string with the last error. +*/ +gchar * AirpcapGetLastError(PAirpcapHandle AdapterHandle); + +/*! + \brief Return the list of available devices + \param PPAllDevs Address to a caller allocated pointer. On success this pointer will receive the head of a list of available devices. + \param Ebuf String that will contain error information if FALSE is returned. The size of the string must be AIRPCAP_ERRBUF_SIZE bytes. + \return TRUE on success. FALSE is returned on failure, in which case Ebuf is filled in with an appropriate error message. + + Here's a snippet of code that shows how to use AirpcapGetDeviceList(): + + \code + gchar Ebuf[AIRPCAP_ERRBUF_SIZE]; + AirpcapDeviceDescription *Desc, *tDesc; + + if(AirpcapGetDeviceList(&Desc, Ebuf) == -1) + { + printf("Unable to get the list of devices: %s\n", Ebuf); + return -1; + } + + for(tDesc = Desc; tDesc; tDesc = tDesc->next) + { + printf("%u) %s (%s)\n", + ++i, + tDesc->Name, + tDesc->Description); + } + + AirpcapFreeDeviceList(Desc); + \endcode +*/ +gboolean AirpcapGetDeviceList(PAirpcapDeviceDescription *PPAllDevs, gchar * Ebuf); + +/*! + \brief Free a list of devices returned by AirpcapGetDeviceList() + \param PAllDevs Head of the list of devices returned by \ref AirpcapGetDeviceList(). +*/ +void AirpcapFreeDeviceList(PAirpcapDeviceDescription PAllDevs); + +/*! + \brief Open an adapter + \param DeviceName Name of the device to open. Use \ref AirpcapGetDeviceList() to get the list of devices. + \param Ebuf String that will contain error information in case of failure. The size of the string must be AIRPCAP_ERRBUF_SIZE bytes. + \return A PAirpcapHandle handle on success. NULL is returned on failure, in which case Ebuf is filled in with an appropriate error message. +*/ +PAirpcapHandle AirpcapOpen(gchar * DeviceName, gchar * Ebuf); + +/*! + \brief Close an adapter + \param AdapterHandle Handle to the adapter to close. +*/ +void AirpcapClose(PAirpcapHandle AdapterHandle); + +/*! + \brief Sets the monitor mode for the specified adapter + \param AdapterHandle Handle to the adapter. + \param MonitorModeEnabled If TRUE, the adapter will be put in monitor mode. If FALSE, the adapter will be configured + for normal operation. + \return TRUE on success. + + When monitor mode is on, the adapter captures all the packets transmitted on the channel. This includes: + + - unicast packets + - multicast packets + - broadcast packets + - control and management packets + + When monitor mode is off, the adapter has a filter on unicast packets to capture only the packets whose MAC + destination address equals to the adapter's address. This means the following frames will be received: + + - unicast packets with the address of the adapter + - multicast packets + - broadcast packets + - beacons and probe requests + + The main reason to turn monitor mode off is that, when not in monitor mode, the adapter will acknowledge the + data frames sent to its address. This is useful when the adapter needs to interact with other devices on the + 802.11 network, because handling the ACKs in software is too slow. + + \note When an adapter is plugged into the system, it's always configured with monitor mode ON. The monitor mode + configuration is not stored persistently, so if you want to turn monitor mode off, you will need to do it + every time you open the adapter. +*/ +gboolean AirpcapSetMonitorMode(PAirpcapHandle AdapterHandle, gboolean MonitorModeEnabled); + +/*! + \brief Returns TRUE if the specified adapter is in monitor mode. + \param AdapterHandle Handle to the adapter. + \param PMonitorModeEnabled User-provided variable that will be set to true if the adapter is in monitor mode. + \return TRUE if the operation is successful. FALSE otherwise. + + \note When an adapter is plugged into the system, it's always configured with monitor mode ON. The monitor mode + configuration is not stored persistently, so if you want to turn monitor mode off, you will need to do it + every time you open the adapter. +*/ +gboolean AirpcapGetMonitorMode(PAirpcapHandle AdapterHandle, gboolean * PMonitorModeEnabled); + +/*! + \brief Set the link type of an adapter + \param AdapterHandle Handle to the adapter. + \param NewLinkType the "link type", i.e. the format of the frames that will be received from the adapter. + \return TRUE on success. + + the "link type" determines how the driver will encode the packets captured from the network. + Aircap supports two link types: + - \ref AIRPCAP_LT_802_11, to capture 802.11 frames (including control frames) without any + power information. Look at the Capture_no_radio example application in the developer's pack + for a reference on how to decode 802.11 frames with this link type. + - \ref AIRPCAP_LT_802_11_PLUS_RADIO, to capture 802.11 frames (including control frames) with a radiotap header + that contains power and channel information. More information about the radiotap header can be found in the + radiotap section. Moreover, the "Capture_radio" example application in + the developer's pack can be used as a reference on how to decode 802.11 frames with radiotap headers. + - \ref AIRPCAP_LT_802_11_PLUS_PPI, to capture 802.11 frames (including control frames) with a Per Packet Information (PPI) + header that contains per-packet meta information like channel and power information. More details on the PPI header can + be found in the PPI online documentation (TODO). +*/ +gboolean AirpcapSetLinkType(PAirpcapHandle AdapterHandle, AirpcapLinkType NewLinkType); + +/*! + \brief Get the link type of the specified adapter + \param AdapterHandle Handle to the adapter. + \param PLinkType Pointer to a caller allocated AirpcapLinkType variable that will contain the link type of the adapter. + \return TRUE on success. + + the "link type" determines how the driver will encode the packets captured from the network. + Aircap supports two link types: + - AIRPCAP_LT_802_11, to capture 802.11 frames (including control frames) without any + power information. Look at the Capture_no_radio example application in the developer's pack + for a reference on how to decode 802.11 frames with this link type. + - AIRPCAP_LT_802_11_PLUS_RADIO, to capture 802.11 frames (including control frames) with a radiotap header + that contains power and channel information. More information about the radiotap header can be found int the + radiotap section. Moreover, the "Capture_radio" example application in + the developer's pack can be used as a reference on how to decode 802.11 frames with radiotap headers. +*/ +gboolean AirpcapGetLinkType(PAirpcapHandle AdapterHandle, PAirpcapLinkType PLinkType); + +/*! + \brief Configures the adapter on whether to include the MAC Frame Check Sequence in the captured packets. + \param AdapterHandle Handle to the adapter. + \param IsFcsPresent TRUE if the packets should include the FCS. FALSE otherwise + \return TRUE on success. + + In the default configuration, the adapter includes the FCS in the captured packets. The MAC Frame Check Sequence + is 4 bytes and is located at the end of the 802.11 packet, with both AIRPCAP_LT_802_11 and AIRPCAP_LT_802_11_PLUS_RADIO + link types. + When the FCS inclusion is turned on, and if the link type is AIRPCAP_LT_802_11_PLUS_RADIO, the radiotap header + that precedes each frame has two additional fields at the end: Padding and FCS. These two fields are not present + when FCS inclusion is off. +*/ +gboolean AirpcapSetFcsPresence(PAirpcapHandle AdapterHandle, gboolean IsFcsPresent); + +/*! + \brief Returns TRUE if the specified adapter includes the MAC Frame Check Sequence in the captured packets + \param AdapterHandle Handle to the adapter. + \param PIsFcsPresent User-provided variable that will be set to true if the adapter is including the FCS. + \return TRUE if the operation is successful. FALSE otherwise. + + In the default configuration, the adapter has FCS inclusion turned on. The MAC Frame Check Sequence is 4 bytes + and is located at the end of the 802.11 packet, with both AIRPCAP_LT_802_11 and AIRPCAP_LT_802_11_PLUS_RADIO + link types. + When the FCS inclusion is turned on, and if the link type is AIRPCAP_LT_802_11_PLUS_RADIO, the radiotap header + that precedes each frame has two additional fields at the end: Padding and FCS. These two fields are not present + when FCS inclusion is off. +*/ +gboolean AirpcapGetFcsPresence(PAirpcapHandle AdapterHandle, gboolean * PIsFcsPresent); + +/*! + \brief Configures the adapter to accept or drop frames with an incorrect Frame Check sequence (FCS). + \param AdapterHandle Handle to the adapter. + \param ValidationType The type of validation the driver will perform. See the documentation of \ref AirpcapValidationType for details. + \return TRUE on success. + + \note By default, the driver is configured in \ref AIRPCAP_VT_ACCEPT_EVERYTHING mode. +*/ +gboolean AirpcapSetFcsValidation(PAirpcapHandle AdapterHandle, AirpcapValidationType ValidationType); + +/*! + \brief Checks if the specified adapter is configured to capture frames with incorrect an incorrect Frame Check Sequence (FCS). + \param AdapterHandle Handle to the adapter. + \param ValidationType Pointer to a user supplied variable that will contain the type of validation the driver will perform. See the documentation of \ref AirpcapValidationType for details. + \return TRUE if the operation is successful. FALSE otherwise. + + \note By default, the driver is configured in \ref AIRPCAP_VT_ACCEPT_EVERYTHING mode. +*/ +gboolean AirpcapGetFcsValidation(PAirpcapHandle AdapterHandle, PAirpcapValidationType ValidationType); + +/*! + \brief Set the list of decryption keys that the driver is going to use with the specified device. + \param AdapterHandle Handle an open adapter instance. + \param KeysCollection Pointer to a \ref PAirpcapKeysCollection structure that contains the keys to be set in the driver. + \return TRUE if the operation is successful. FALSE otherwise. + + The AirPcap driver is able to use a set of decryption keys to decrypt the traffic transmitted on a specific SSID. If one of the + keys corresponds to the one the frame has been encrypted with, the driver will perform decryption and return the cleartext frames + to the application. + + This function allows to set the adapter-specific set of keys. These keys will be used by the specified adapter only, + and will not be used by other airpcap devices besides the specified one. + + At this time, the only supported decryption method is WEP. + + The keys are applied to the packets in the same order they appear in the KeysCollection structure until the packet is + correctly decrypted, therefore putting frequently used keys at the beginning of the structure improves performance. + + \note: when you change the set of keys from an open capture instance, the change will be + immediately reflected on all the other capture instances. +*/ +gboolean AirpcapSetDeviceKeys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection); + +/*! + \brief Returns the list of decryption keys in the driver that are currently associated with the specified device + \param AdapterHandle Handle to an open adapter instance. + \param KeysCollection User-allocated PAirpcapKeysCollection structure that will be filled with the keys. + \param PKeysCollectionSize \b IN: pointer to a user-allocated variable that contains the length of the KeysCollection structure, in bytes. + \b OUT: amount of data moved by the driver in the buffer pointed by KeysBuffer, in bytes. + \return TRUE if the operation is successful. If an error occurs, the return value is FALSE and KeysCollectionSize is zero. + If the provided buffer is too small to contain the keys, the return value is FALSE and KeysCollectionSize contains the + needed KeysCollection length, in bytes. If the device doesn't have any decryption key configured, the return value is TRUE, and + KeysCollectionSize will be zero. + + This function returns the adapter-specific set of keys. These keys are used by the specified adapter only, + and not by other airpcap devices besides the specified one. + + The AirPcap driver is able to use a set of decryption keys to decrypt the traffic transmitted on a specific SSID. If one of the + keys corresponds to the one the frame has been encrypted with, the driver will perform decryption and return the cleartext frames + to the application. + The driver supports, for every device, multiple keys at the same time. + + The configured decryption keys are device-specific, therefore AirpcapGetDeviceKeys() will return a different set of keys + when called on different devices. + + At this time, the only supported decryption method is WEP. +*/ +gboolean AirpcapGetDeviceKeys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize); + +/*! + \brief Set the global list of decryption keys that the driver is going to use with all the devices. + \param AdapterHandle Handle an open adapter instance. + \param KeysCollection Pointer to a \ref PAirpcapKeysCollection structure that contains the keys to be set in the driver. + \return TRUE if the operation is successful. FALSE otherwise. + + The AirPcap driver is able to use a set of decryption keys to decrypt the traffic transmitted on a specific SSID. If one of the + keys corresponds to the one the frame has been encrypted with, the driver will perform decryption and return the cleartext frames + to the application. + + This function allows to set the global driver set of keys. These keys will be used by all the adapters plugged in + the machine. + + At this time, the only supported decryption method is WEP. + + The keys are applied to the packets in the same order they appear in the KeysCollection structure until the packet is + correctly decrypted, therefore putting frequently used keys at the beginning of the structure improves performance. + + \note: when you change the set of keys from an open capture instance, the change will be + immediately reflected on all the other capture instances. +*/ +gboolean AirpcapSetDriverKeys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection); + +/*! + \brief Returns the global list of decryption keys in the driver that are associated with all the devices. + \param AdapterHandle Handle to an open adapter instance. + \param KeysCollection User-allocated PAirpcapKeysCollection structure that will be filled with the keys. + \param PKeysCollectionSize \b IN: pointer to a user-allocated variable that contains the length of the KeysCollection structure, in bytes. + \b OUT: amount of data moved by the driver in the buffer pointed by KeysBuffer, in bytes. + \return TRUE if the operation is successful. If an error occurs, the return value is FALSE and KeysCollectionSize is zero. + If the provided buffer is too small to contain the keys, the return value is FALSE and KeysCollectionSize contains the + needed KeysCollection length, in bytes. If the device doesn't have any decryption key configured, the return value is TRUE, and + KeysCollectionSize will be zero. + + This function returns the global driver set of keys. These keys will be used by all the adapters plugged in + the machine. + + The AirPcap driver is able to use a set of decryption keys to decrypt the traffic transmitted on a specific SSID. If one of the + keys corresponds to the one the frame has been encrypted with, the driver will perform decryption and return the cleartext frames + to the application. + + At this time, the only supported decryption method is WEP. +*/ +gboolean AirpcapGetDriverKeys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize); + +/*! + \brief Turns on or off the decryption of the incoming frames with the adapter-specific keys. + \param AdapterHandle Handle to the adapter. + \param Enable Either \ref AIRPCAP_DECRYPTION_ON or \ref AIRPCAP_DECRYPTION_OFF + \return TRUE on success. + + The adapter-specific decryption keys can be configured with the \ref AirpcapSetDeviceKeys() function. + \note By default, the driver is configured with \ref AIRPCAP_DECRYPTION_ON. +*/ +gboolean AirpcapSetDecryptionState(PAirpcapHandle AdapterHandle, AirpcapDecryptionState Enable); + +/*! + \brief Tells if this open instance is configured to perform the decryption of the incoming frames with the adapter-specific keys. + \param AdapterHandle Handle to the adapter. + \param PEnable Pointer to a user supplied variable that will contain the decryption configuration. See \ref PAirpcapDecryptionState for details. + \return TRUE if the operation is successful. FALSE otherwise. + + The adapter-specific decryption keys can be configured with the \ref AirpcapSetDeviceKeys() function. + \note By default, the driver is configured with \ref AIRPCAP_DECRYPTION_ON. +*/ +gboolean AirpcapGetDecryptionState(PAirpcapHandle AdapterHandle, PAirpcapDecryptionState PEnable); + +/*! + \brief Turns on or off the decryption of the incoming frames with the global driver set of keys. + \param AdapterHandle Handle to the adapter. + \param Enable Either \ref AIRPCAP_DECRYPTION_ON or \ref AIRPCAP_DECRYPTION_OFF + \return TRUE on success. + + The global decryption keys can be configured with the \ref AirpcapSetDriverKeys() function. + \note By default, the driver is configured with \ref AIRPCAP_DECRYPTION_ON. +*/ +gboolean AirpcapSetDriverDecryptionState(PAirpcapHandle AdapterHandle, AirpcapDecryptionState Enable); + +/*! + \brief Tells if this open instance is configured to perform the decryption of the incoming frames with the global driver set of keys. + \param AdapterHandle Handle to the adapter. + \param PEnable Pointer to a user supplied variable that will contain the decryption configuration. See \ref PAirpcapDecryptionState for details. + \return TRUE if the operation is successful. FALSE otherwise. + + The global decryption keys can be configured with the \ref AirpcapSetDriverKeys() function. + \note By default, the driver is configured with \ref AIRPCAP_DECRYPTION_ON. +*/ +gboolean AirpcapGetDriverDecryptionState(PAirpcapHandle AdapterHandle, PAirpcapDecryptionState PEnable); + +/*! + \brief Set the radio channel of a device + \param AdapterHandle Handle to the adapter. + \param Channel the new channel to set. + \return TRUE on success. + + The list of available channels can be retrieved with \ref AirpcapGetDeviceSupportedChannels(). The default channel setting is 6. + + \note this is a device-related function: when you change the channel from an open capture instance, the change will be + immediately reflected on all the other capture instances. +*/ +gboolean AirpcapSetDeviceChannel(PAirpcapHandle AdapterHandle, guint Channel); + +/*! + \brief Get the radio channel of a device + \param AdapterHandle Handle to the adapter. + \param PChannel Pointer to a user-supplied variable into which the function will copy the currently configured radio channel. + \return TRUE on success. + + The list of available channels can be retrieved with \ref AirpcapGetDeviceSupportedChannels(). The default channel setting is 6. + + \note this is a device-related function: when you change the channel from an open capture instance, the change will be + immediately reflected on all the other capture instances. +*/ +gboolean AirpcapGetDeviceChannel(PAirpcapHandle AdapterHandle, guint * PChannel); + +/*! + \brief Set the size of the kernel packet buffer for this adapter + \param AdapterHandle Handle to the adapter. + \param BufferSize New size, in bytes. + \return TRUE on success. + + Every AirPcap open instance has an associated kernel buffer, whose default size is 1 Mbyte. + This function can be used to change the size of this buffer, and can be called at any time. + A bigger kernel buffer size decreases the risk of dropping packets during network bursts or when the + application is busy, at the cost of higher kernel memory usage. + + \note don't use this function unless you know what you are doing. Due to caching issues and bigger non-paged + memory consumption, bigger buffer sizes can decrease the capture performance instead of improving it. +*/ +gboolean AirpcapSetKernelBuffer(PAirpcapHandle AdapterHandle, guint BufferSize); + +/*! + \brief Get the size of the kernel packet buffer for this adapter + \param AdapterHandle Handle to the adapter. + \param PSizeBytes User-allocated variable that will be filled with the size of the kernel buffer. + \return TRUE on success. + + Every AirPcap open instance has an associated kernel buffer, whose default size is 1 Mbyte. + This function can be used to get the size of this buffer. +*/ +gboolean AirpcapGetKernelBufferSize(PAirpcapHandle AdapterHandle, guint * PSizeBytes); + +/*! + \brief Saves the configuration of the specified adapter in the registry, so that it becomes the default for this adapter. + \param AdapterHandle Handle to the adapter. + \return TRUE on success. FALSE on failure. + + Almost all the AirPcap calls that modify the configuration (\ref AirpcapSetLinkType(), \ref AirpcapSetFcsPresence(), + \ref AirpcapSetFcsValidation(), \ref AirpcapSetKernelBuffer(), \ref AirpcapSetMinToCopy()) + affect only the referenced AirPcap open instance. This means that if you do another \ref AirpcapOpen() on the same + adapter, the configuration changes will not be remembered, and the new adapter handle will have default configuration + settings. + + Exceptions to this rule are the \ref AirpcapSetDeviceChannel() and \ref AirpcapSetDeviceKeys() functions: a channel change is + reflected on all the open instances, and remembered until the next call to \ref AirpcapSetDeviceChannel(), until the adapter + is unplugged, or until the machine is powered off. Same thing for the configuration of the WEP keys. + + AirpcapStoreCurConfigAsAdapterDefault() stores the configuration of the give open instance as the default for the adapter: + all the instances opened in the future will have the same configuration that this adapter currently has. + The configuration is stored in the registry, therefore it is remembered even when the adapter is unplugged or the + machine is turned off. However, an adapter doesn't bring its configuration with it from machine to machine. + + the configuration information saved in the registry includes the following parameters: + - channel + - kernel buffer size + - mintocopy + - link type + - CRC presence + - Encryption keys + - Encryption Enabled/Disabled state + + The configuration is adapter-specific. This means that changing the configuration of an adapter + doesn't modify the one of the other adapters that are currently used or that will be used in the future. + + \note AirpcapStoreCurConfigAsAdapterDefault() must have exclusive access to the adapter -- it + will fail if more than one AirPcap handle is opened at the same time for this adapter. + AirpcapStoreCurConfigAsAdapterDefault() needs administrator privileges. It will fail if the calling user + is not a local machine administrator. +*/ +gboolean AirpcapStoreCurConfigAsAdapterDefault(PAirpcapHandle AdapterHandle); + +/*! + \brief Set the BPF kernel filter for an adapter + \param AdapterHandle Handle to the adapter. + \param Instructions pointer to the first BPF instruction in the array. Corresponds to the bf_insns + in a bpf_program structure (see the WinPcap documentation at http://www.winpcap.org/devel.htm). + \param Len Number of instructions in the array pointed by the previous field. Corresponds to the bf_len in + a a bpf_program structure (see the WinPcap documentation at http://www.winpcap.org/devel.htm). + \return TRUE on success. + + The AirPcap driver is able to perform kernel-level filtering using the standard BPF pseudo-machine format. You can read + the WinPcap documentation at http://www.winpcap.org/devel.htm for more details on the BPF filtering mechanism. + + A filter can be automatically created by using the pcap_compile() function of the WinPcap API. This function + converts a human readable text expression with the tcpdump/libpcap syntax into a BPF program. + If your program doesn't link wpcap, but you need to generate the code for a particular filter, you can run WinDump + with the -d or -dd or -ddd flags to obtain the pseudocode. + +*/ +gboolean AirpcapSetFilter(PAirpcapHandle AdapterHandle, void * Instructions, guint Len); + +/*! + \brief Return the MAC address of an adapter. + \param AdapterHandle Handle to the adapter. + \param PMacAddress Pointer to a user allocated MAC address. + The size of this buffer needs to be at least 6 bytes. + \return TRUE on success. +*/ +gboolean AirpcapGetMacAddress(PAirpcapHandle AdapterHandle, PAirpcapMacAddress PMacAddress); + +/*! + \brief Set the mintocopy parameter for an open adapter + \param AdapterHandle Handle to the adapter. + \param MinToCopy is the mintocopy size in bytes. + \return TRUE on success. + + When the number of bytes in the kernel buffer changes from less than mintocopy bytes to greater than or equal to mintocopy bytes, + the read event is signalled (see \ref AirpcapGetReadEvent()). A high value for mintocopy results in poor responsiveness since the + driver may signal the application "long" after the arrival of the packet. And a high value results in low CPU loading + by minimizing the number of user/kernel context switches. + A low MinToCopy results in good responsiveness since the driver will signal the application close to the arrival time of + the packet. This has higher CPU loading over the first approach. +*/ +gboolean AirpcapSetMinToCopy(PAirpcapHandle AdapterHandle, guint MinToCopy); + +/*! + \brief Gets an event that is signaled when that is signalled when packets are available in the kernel buffer (see \ref AirpcapSetMinToCopy()). + \param AdapterHandle Handle to the adapter. + \param PReadEvent Pointer to a user-supplied handle that in which the read event will be copied. + \return TRUE on success. + + \note the event is signalled when at least mintocopy bytes are present in the kernel buffer (see \ref AirpcapSetMinToCopy()). + This event can be used by WaitForSingleObject() and WaitForMultipleObjects() to create blocking behavior when reading + packets from one or more adapters (see \ref AirpcapRead()). +*/ +gboolean AirpcapGetReadEvent(PAirpcapHandle AdapterHandle, void *** PReadEvent); + +/*! + \brief Fills a user-provided buffer with zero or more packets that have been captured on the referenced adapter. + \param AdapterHandle Handle to the adapter. + \param Buffer pointer to the buffer that will be filled with captured packets. + \param BufSize size of the input buffer that will contain the packets, in bytes. + \param PReceievedBytes Pointer to a user supplied variable that will receive the number of bytes copied by AirpcapRead. + Can be smaller than BufSize. + \return TRUE on success. + + 802.11 frames are returned by the driver in buffers. Every 802.11 frame in the buffer is preceded by a \ref AirpcapBpfHeader structure. + The suggested way to use an AirPcap adapter is through the pcap API exported by wpcap.dll. If this is not + possible, the Capture_radio and Capture_no_radio examples in the AirPcap developer's pack show how to properly decode the + packets in the read buffer returned by AirpcapRead(). + + \note this function is NOT blocking. Blocking behavior can be obtained using the event returned + by \ref AirpcapGetReadEvent(). See also \ref AirpcapSetMinToCopy(). +*/ +gboolean AirpcapRead(PAirpcapHandle AdapterHandle, guint8 * Buffer, guint BufSize, guint * PReceievedBytes); + +/*! + \brief Transmits a packet. + \param AdapterHandle Handle to the adapter. + \param TxPacket Pointer to a buffer that contains the packet to be transmitted. + \param PacketLen Length of the buffer pointed by the TxPacket argument, in bytes. + \return TRUE on success. + + The packet will be transmitted on the channel the device is currently set. To change the device adapter, use the + \ref AirpcapSetDeviceChannel() function. + + If the linktype of the adapter is AIRPCAP_LT_802_11, the buffer pointed by TxPacket should contain just the 802.11 + packet, without additional information. The packet will be transmitted at 1Mbps. + + If the linktype of the adapter is AIRPCAP_LT_802_11_PLUS_RADIO, the buffer pointed by TxPacket should contain a radiotap + header followed by the 802.11 packet. AirpcapWrite will use the rate information in the radiotap header when + transmitting the packet. +*/ +gboolean AirpcapWrite(PAirpcapHandle AdapterHandle, gchar * TxPacket, guint32 PacketLen); + +/*! + \brief Get per-adapter WinPcap-compatible capture statistics. + \param AdapterHandle Handle to the adapter. + \param PStats pointer to a user-allocated AirpcapStats structure that will be filled with statistical information. + \return TRUE on success. +*/ +gboolean AirpcapGetStats(PAirpcapHandle AdapterHandle, PAirpcapStats PStats); + +/*! + \brief Get the number of LEDs the referenced adapter has available. + \param AdapterHandle Handle to the adapter. + \param NumberOfLeds Number of LEDs available on this adapter. + \return TRUE on success. +*/ +gboolean AirpcapGetLedsNumber(PAirpcapHandle AdapterHandle, guint * NumberOfLeds); + +/*! + \brief Turn on one of the adapter's LEDs. + \param AdapterHandle Handle to the adapter. + \param LedNumber zero-based identifier of the LED to turn on. + \return TRUE on success. +*/ +gboolean AirpcapTurnLedOn(PAirpcapHandle AdapterHandle, guint LedNumber); + +/*! + \brief Turn off one of the adapter's LEDs. + \param AdapterHandle Handle to the adapter. + \param LedNumber zero-based identifier of the LED to turn off. + \return TRUE on success. +*/ +gboolean AirpcapTurnLedOff(PAirpcapHandle AdapterHandle, guint LedNumber); + +/*! + \brief Set the channel of a device through its radio frequency. In case of 802.11n enabled devices, it sets the extension channel, if used. + \param AdapterHandle Handle to the adapter. + \param ChannelInfo The new channel information to set. + \return TRUE on success. + + \note this is a device-related function: when you change the channel from an open capture instance, the change will be + immediately reflected on all the other capture instances. +*/ +gboolean AirpcapSetDeviceChannelEx(PAirpcapHandle AdapterHandle, AirpcapChannelInfo ChannelInfo); + +/*! + \brief Get the channel of a device through its radiofrequency. In case of 802.11n enabled devices, it gets the extension channel, if in use. + \param AdapterHandle Handle to the adapter. + \param PChannelInfo Pointer to a user-supplied variable into which the function will copy the currently configured channel information. + \return TRUE on success. + + \note this is a device-related function: when you change the channel from an open capture instance, the change will be + immediately reflected on all the other capture instances. +*/ +gboolean AirpcapGetDeviceChannelEx(PAirpcapHandle AdapterHandle, PAirpcapChannelInfo PChannelInfo); + +/*! + \brief Get the list of supported channels for a given device. In case of a 802.11n capable device, information related to supported extension channels is also reported. + + Every control channel is listed multiple times, one for each different supported extension channel. For example channel 6 (2437MHz) is usually listed three times: + - Frequency 2437 Extension +1. Control channel is 6, extension channel is 10. + - Frequency 2437 Extension 0. Control channel is 6, no extension channel is used (20MHz channel and legacy mode). + - Frequency 2437 Extension -1. Control channel is 6, extension channel is 2. + \param AdapterHandle Handle to the adapter. + \param ppChannelInfo Pointer to a user-supplied variable that will point to an array of supported channel. Such list must not be freed by the caller + \param pNumChannelInfo Number of channels returned in the array. + \return TRUE on success. + + \note The supported channels are not listed in any specific order. +*/ +gboolean AirpcapGetDeviceSupportedChannels(PAirpcapHandle AdapterHandle, PAirpcapChannelInfo *ppChannelInfo, guint * pNumChannelInfo); + +/*! + \brief Converts a given frequency to the corresponding channel. + + \param Frequency Frequency of the channel, in MHz. + \param PChannel Pointer to a user-supplied variable that will contain the channel number on success. + \param PBand Pointer to a user-supplied variable that will contain the band (a or b/g) of the given channel. + \return TRUE on success, i.e. the frequency corresponds to a valid a or b/g channel. +*/ +gboolean AirpcapConvertFrequencyToChannel(guint Frequency, guint * PChannel, PAirpcapChannelBand PBand); + +/*! + \brief Converts a given channel to the corresponding frequency. + + \param Channel Channel number to be converted. + \param PFrequency Pointer to a user-supplied variable that will contain the channel frequency in MHz on success. + \return TRUE on success, i.e. the given channel number exists. +*/ +gboolean AirpcapConvertChannelToFrequency(guint Channel, guint * PFrequency); + + +/*@}*/ + +#endif /* __AIRPCAP_DRIVER__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(AIRPCAP_H__EAE405F5_0171_9592_B3C2_C19EC426AD34__INCLUDED_) */ diff --git a/caputils/airpcap_loader.c b/caputils/airpcap_loader.c new file mode 100644 index 0000000000..ed2d135b6c --- /dev/null +++ b/caputils/airpcap_loader.c @@ -0,0 +1,2552 @@ +/* airpcap_loader.c + * + * Giorgio Tino + * Copyright (c) CACE Technologies, LLC 2006 + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 2000 Gerald Combs + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#ifdef HAVE_AIRPCAP + +#ifdef HAVE_LIBPCAP +#include +#include + + +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ui/capture_ui_utils.h" +#include "ui/simple_dialog.h" + +#include +#include + + +/* + * Set to TRUE if the DLL was successfully loaded AND all functions + * are present. + */ +static gboolean AirpcapLoaded = FALSE; + +#ifdef _WIN32 +/* + * We load dynamically the dag library in order link it only when + * it's present on the system + */ +static void * AirpcapLib = NULL; + +static AirpcapGetLastErrorHandler g_PAirpcapGetLastError; +static AirpcapSetKernelBufferHandler g_PAirpcapSetKernelBuffer; +static AirpcapSetFilterHandler g_PAirpcapSetFilter; +static AirpcapGetMacAddressHandler g_PAirpcapGetMacAddress; +static AirpcapSetMinToCopyHandler g_PAirpcapSetMinToCopy; +static AirpcapGetReadEventHandler g_PAirpcapGetReadEvent; +static AirpcapReadHandler g_PAirpcapRead; +static AirpcapGetStatsHandler g_PAirpcapGetStats; +#endif + +static int AirpcapVersion = 3; + +static AirpcapGetDeviceListHandler g_PAirpcapGetDeviceList; +static AirpcapFreeDeviceListHandler g_PAirpcapFreeDeviceList; +static AirpcapOpenHandler g_PAirpcapOpen; +static AirpcapCloseHandler g_PAirpcapClose; +static AirpcapGetLinkTypeHandler g_PAirpcapGetLinkType; +static AirpcapSetLinkTypeHandler g_PAirpcapSetLinkType; +static AirpcapTurnLedOnHandler g_PAirpcapTurnLedOn; +static AirpcapTurnLedOffHandler g_PAirpcapTurnLedOff; +static AirpcapGetDeviceChannelHandler g_PAirpcapGetDeviceChannel; +static AirpcapSetDeviceChannelHandler g_PAirpcapSetDeviceChannel; +static AirpcapGetFcsPresenceHandler g_PAirpcapGetFcsPresence; +static AirpcapSetFcsPresenceHandler g_PAirpcapSetFcsPresence; +static AirpcapGetFcsValidationHandler g_PAirpcapGetFcsValidation; +static AirpcapSetFcsValidationHandler g_PAirpcapSetFcsValidation; +static AirpcapGetDeviceKeysHandler g_PAirpcapGetDeviceKeys; +static AirpcapSetDeviceKeysHandler g_PAirpcapSetDeviceKeys; +static AirpcapGetDriverKeysHandler g_PAirpcapGetDriverKeys; +static AirpcapSetDriverKeysHandler g_PAirpcapSetDriverKeys; +static AirpcapGetDecryptionStateHandler g_PAirpcapGetDecryptionState; +static AirpcapSetDecryptionStateHandler g_PAirpcapSetDecryptionState; +static AirpcapGetDriverDecryptionStateHandler g_PAirpcapGetDriverDecryptionState; +static AirpcapSetDriverDecryptionStateHandler g_PAirpcapSetDriverDecryptionState; +static AirpcapStoreCurConfigAsAdapterDefaultHandler g_PAirpcapStoreCurConfigAsAdapterDefault; +static AirpcapGetVersionHandler g_PAirpcapGetVersion; +static AirpcapSetDeviceChannelExHandler g_PAirpcapSetDeviceChannelEx; +static AirpcapGetDeviceChannelExHandler g_PAirpcapGetDeviceChannelEx; +static AirpcapGetDeviceSupportedChannelsHandler g_PAirpcapGetDeviceSupportedChannels; + +/* Airpcap interface list */ +GList *airpcap_if_list = NULL; + +/* Airpcap current selected interface */ +airpcap_if_info_t *airpcap_if_selected = NULL; + +/* Airpcap current active interface */ +airpcap_if_info_t *airpcap_if_active = NULL; + +/* WLAN preferences pointer */ +module_t *wlan_prefs = NULL; + +Dot11Channel *pSupportedChannels; +guint numSupportedChannels; + +static AirpcapChannelInfo LegacyChannels[] = +{ + {2412, 0, {0,0,0}}, + {2417, 0, {0,0,0}}, + {2422, 0, {0,0,0}}, + {2427, 0, {0,0,0}}, + {2432, 0, {0,0,0}}, + {2437, 0, {0,0,0}}, + {2442, 0, {0,0,0}}, + {2447, 0, {0,0,0}}, + {2452, 0, {0,0,0}}, + {2457, 0, {0,0,0}}, + {2462, 0, {0,0,0}}, + {2467, 0, {0,0,0}}, + {2472, 0, {0,0,0}}, + {2484, 0, {0,0,0}}, +}; + +static guint num_legacy_channels = 14; + +/* + * Callback used by the load_wlan_keys() routine in order to read a WEP decryption key + */ +static guint +get_wep_key(pref_t *pref, gpointer ud) +{ + gchar *key_string = NULL; + guint8 key_type = AIRPDCAP_KEY_TYPE_WEP; + keys_cb_data_t* user_data; + uat_t *uat; + guint i; + const char* err = NULL; + uat_wep_key_record_t* wep_keys; + decryption_key_t* new_key; + + /* Retrieve user data info */ + user_data = (keys_cb_data_t*)ud; + + if (g_ascii_strcasecmp(pref->name, "wep_key_table") == 0 && pref->type == PREF_UAT) + { + uat = pref->varp.uat; + /* This is just a sanity check. UAT should be loaded */ + if (!uat->loaded) + { + uat_load(uat, &err); + if (err != NULL) + return 1; + } + + for (i = 0, wep_keys = (uat_wep_key_record_t*)*uat->user_ptr; i < *uat->nrows_p; i++, wep_keys++) + { + /* strip out key type if present */ + if (g_ascii_strncasecmp(wep_keys->string, STRING_KEY_TYPE_WEP ":", 4) == 0) { + key_type = AIRPDCAP_KEY_TYPE_WEP; + key_string = (gchar*)wep_keys->string+4; + } + else if (g_ascii_strncasecmp(wep_keys->string, STRING_KEY_TYPE_WPA_PWD ":", 8) == 0) { + key_string = (gchar*)wep_keys->string+8; + key_type = AIRPDCAP_KEY_TYPE_WPA_PWD; + } + else if (g_ascii_strncasecmp(wep_keys->string, STRING_KEY_TYPE_WPA_PSK ":", 8) == 0) { + key_string = (gchar*)wep_keys->string+8; + key_type = AIRPDCAP_KEY_TYPE_WPA_PSK; + } + else { + key_type = wep_keys->key; + key_string = (gchar*)wep_keys->string; + } + + /* Here we have the string describing the key... */ + new_key = parse_key_string(key_string, key_type); + + if (new_key != NULL) + { + /* Key is added only if not null ... */ + user_data->list = g_list_append(user_data->list,new_key); + user_data->number_of_keys++; + user_data->current_index++; + } + } + } + return 0; +} + +/* Returs TRUE if the WEP key is valid, false otherwise */ +gboolean +wep_key_is_valid(char* key) +{ + GString *new_key_string; + guint i=0; + + if (key == NULL) + return FALSE; + + new_key_string = g_string_new(key); + + if ( ((new_key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((new_key_string->len) < 2)) + { + g_string_free(new_key_string,FALSE); + return FALSE; + } + if ((new_key_string->len % 2) != 0) + { + g_string_free(new_key_string,FALSE); + return FALSE; + } + for(i = 0; i < new_key_string->len; i++) + { + if (!g_ascii_isxdigit(new_key_string->str[i])) + { + g_string_free(new_key_string,FALSE); + return FALSE; + } + } + + g_string_free(new_key_string,FALSE); + return TRUE; +} + +/* Callback used by the save_wlan_keys() routine in order to write a decryption key */ +static guint +set_wep_key(pref_t *pref, gpointer ud _U_) +{ + keys_cb_data_t* user_data; + uat_t *uat; + gint i; + const char* err = NULL; + uat_wep_key_record_t uat_key; + + decryption_key_t* new_key; + + /* Retrieve user data info */ + user_data = (keys_cb_data_t*)ud; + + if (g_ascii_strcasecmp(pref->name, "wep_key_table") == 0 && pref->type == PREF_UAT) + { + uat = pref->varp.uat; + if (!uat->loaded) + { + /* UAT will only be loaded if previous keys exist, so it may need + to be loaded now */ + uat_load(uat, &err); + if (err != NULL) + return 1; + + uat->loaded = 1; + } + /* Free the old records */ + uat_clear(uat); + + for (i = 0; i < user_data->number_of_keys; i++) + { + new_key = (decryption_key_t*)g_list_nth_data(user_data->list,i); + + uat_key.string = get_key_string(new_key); + uat_key.key = new_key->type; + uat_add_record(uat, &uat_key, TRUE); + } + + uat_save(uat, &err); + if (err != NULL) + return 1; + } + + return 0; +} + +/* + * Function used to read the Decryption Keys from the preferences and store them + * properly into the airpcap adapter. + */ +gboolean +load_wlan_driver_wep_keys(void) +{ + keys_cb_data_t* user_data; + guint i; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + /* Fill the structure */ + user_data->list = NULL; + user_data->current_index = 0; + user_data->number_of_keys= 0; /* Still unknown */ + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)user_data); + + /* Now the key list should be filled */ + + /* + * Signal that we've changed things, and run the 802.11 dissector's + * callback + */ + wlan_prefs->prefs_changed = TRUE; + + prefs_apply(wlan_prefs); + + write_wlan_driver_wep_keys_to_registry(user_data->list); + + /* FREE MEMORY */ + /* free the WEP key string */ + for(i=0;ilist);i++) + { + g_free(g_list_nth(user_data->list,i)->data); + } + + /* free the (empty) list */ + g_list_free(user_data->list); + + /* free the user_data structure */ + g_free(user_data); + + /* airpcap_if_info_free(fake_info_if); */ + + return TRUE; +} + +/* + * This function will tell the airpcap driver the key list to use + * This will be stored into the registry... + */ +gboolean +write_wlan_wep_keys_to_registry(airpcap_if_info_t* info_if, GList* key_list) +{ + guint i,j; + GString *new_key; + gchar s[3]; + PAirpcapKeysCollection KeysCollection; + guint KeysCollectionSize; + guint8 KeyByte; + guint keys_in_list = 0; + decryption_key_t* key_item = NULL; + + keys_in_list = g_list_length(key_list); + + /* + * Calculate the size of the keys collection + */ + KeysCollectionSize = (guint)AirpcapKeysCollectionSize(keys_in_list); + + /* + * Allocate the collection + */ + KeysCollection = (PAirpcapKeysCollection)g_malloc(KeysCollectionSize); + if (!KeysCollection) + { + return FALSE; + } + + /* + * Populate the key collection + */ + KeysCollection->nKeys = keys_in_list; + + for(i = 0; i < keys_in_list; i++) + { + KeysCollection->Keys[i].KeyType = AIRPDCAP_KEY_TYPE_WEP; + + /* Retrieve the Item corresponding to the i-th key */ + key_item = (decryption_key_t*)g_list_nth_data(key_list,i); + new_key = g_string_new(key_item->key->str); + + KeysCollection->Keys[i].KeyLen = (guint) new_key->len / 2; + memset(&KeysCollection->Keys[i].KeyData, 0, sizeof(KeysCollection->Keys[i].KeyData)); + + for(j = 0 ; j < new_key->len; j += 2) + { + s[0] = new_key->str[j]; + s[1] = new_key->str[j+1]; + s[2] = '\0'; + KeyByte = (guint8)strtol(s, NULL, 16); + KeysCollection->Keys[i].KeyData[j / 2] = KeyByte; + } + + g_string_free(new_key,TRUE); + + } + /* + * Free the old adapter key collection! + */ + if (info_if->keysCollection != NULL) + g_free(info_if->keysCollection); + + /* + * Set this collection ad the new one + */ + info_if->keysCollection = KeysCollection; + info_if->keysCollectionSize = KeysCollectionSize; + + /* + * Configuration must be saved + */ + info_if->saved = FALSE; + + /* + * Write down the changes to the registry + */ + airpcap_save_selected_if_configuration(info_if); + + return TRUE; +} + +/* + * This function will tell the airpcap driver the key list to use + * This will be stored into the registry... + */ +gboolean +write_wlan_driver_wep_keys_to_registry(GList* key_list) +{ + guint i,j,k,n,y; + GString *new_key; + gchar s[3]; + PAirpcapKeysCollection KeysCollection; + guint KeysCollectionSize; + guint8 KeyByte; + guint keys_in_list = 0; + decryption_key_t* key_item = NULL; + airpcap_if_info_t* fake_info_if = NULL; + + /* Create the fake_info_if from the first adapter of the list */ + fake_info_if = airpcap_driver_fake_if_info_new(); + + if (fake_info_if == NULL) + return FALSE; + + /* + * XXX - When WPA will be supported, change this to: keys_in_list = g_list_length(key_list); + * but right now we will have to count only the WEP keys (or we will have a malloc-mess :-) ) + */ + n = g_list_length(key_list); + for(k = 0; k < n; k++ ) + if (((decryption_key_t*)g_list_nth_data(key_list,k))->type == AIRPDCAP_KEY_TYPE_WEP) + keys_in_list++; + + /* + * Calculate the size of the keys collection + */ + KeysCollectionSize = (guint)AirpcapKeysCollectionSize(keys_in_list); + + /* + * Allocate the collection + */ + KeysCollection = (PAirpcapKeysCollection)g_malloc(KeysCollectionSize); + if (!KeysCollection) + { + return FALSE; + } + + /* + * Populate the key collection + */ + KeysCollection->nKeys = keys_in_list; + + /* + * XXX - If we have, let's say, six keys, the first three are WEP, then two are WPA, and the + * last is WEP, we have to scroll the whole list (n) but increment the array counter only + * when a WEP key is found (y) .. When WPA will be supported by the driver, I'll have to change + * this + */ + y = 0; /* Current position in the key list */ + + for(i = 0; i < n; i++) + { + /* Retrieve the Item corresponding to the i-th key */ + key_item = (decryption_key_t*)g_list_nth_data(key_list,i); + + /* + * XXX - The AIRPDCAP_KEY_TYPE_WEP is the only supported right now! + * We will have to modify the AirpcapKey structure in order to + * support the other two types! What happens now, is that simply the + * not supported keys will just be discarded (they will be saved in Wireshark though) + */ + if (key_item->type == AIRPDCAP_KEY_TYPE_WEP) + { + KeysCollection->Keys[y].KeyType = AIRPDCAP_KEY_TYPE_WEP; + + new_key = g_string_new(key_item->key->str); + + KeysCollection->Keys[y].KeyLen = (guint) new_key->len / 2; + memset(&KeysCollection->Keys[y].KeyData, 0, sizeof(KeysCollection->Keys[y].KeyData)); + + for(j = 0 ; j < new_key->len; j += 2) + { + s[0] = new_key->str[j]; + s[1] = new_key->str[j+1]; + s[2] = '\0'; + KeyByte = (guint8)strtol(s, NULL, 16); + KeysCollection->Keys[y].KeyData[j / 2] = KeyByte; + } + /* XXX - Change when WPA will be supported!!! */ + y++; + g_string_free(new_key,TRUE); + } + else if (key_item->type == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - The driver cannot deal with this kind of key yet... */ + } + else if (key_item->type == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - The driver cannot deal with this kind of key yet... */ + } + } + + /* + * Free the old adapter key collection! + */ + if (fake_info_if->keysCollection != NULL) + g_free(fake_info_if->keysCollection); + + /* + * Set this collection ad the new one + */ + fake_info_if->keysCollection = KeysCollection; + fake_info_if->keysCollectionSize = KeysCollectionSize; + + /* + * Configuration must be saved + */ + fake_info_if->saved = FALSE; + + /* + * Write down the changes to the registry + */ + airpcap_save_driver_if_configuration(fake_info_if); + + airpcap_if_info_free(fake_info_if); + + return TRUE; +} + +/* + * Function used to save to the preference file the Decryption Keys. + */ +int +save_wlan_driver_wep_keys(void) +{ + GList* key_list = NULL; + char* tmp_key = NULL; + guint keys_in_list,i; + keys_cb_data_t* user_data; + airpcap_if_info_t* fake_info_if = NULL; + + /* Create the fake_info_if from the first adapter of the list */ + fake_info_if = airpcap_driver_fake_if_info_new(); + + if (fake_info_if == NULL) + return 0; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + /* Number of keys in key list */ + if (fake_info_if->keysCollectionSize != 0) + keys_in_list = AirpcapKeysCollectionSizeToKeyCount(fake_info_if->keysCollectionSize); + else + keys_in_list = 0; + + for(i=0; ikeysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + tmp_key = airpcap_get_key_string(fake_info_if->keysCollection->Keys[i]); + key_list = g_list_append(key_list,g_strdup(tmp_key)); + g_free(tmp_key); + } + } + + /* Now we know the exact number of WEP keys in the list, so store it ... */ + keys_in_list = g_list_length(key_list); + + /* Fill the structure */ + user_data->list = key_list; + user_data->current_index = 0; + user_data->number_of_keys= keys_in_list; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, set_wep_key, (gpointer)user_data); + + /* Signal that we've changed things, and run the 802.11 dissector's + * callback */ + wlan_prefs->prefs_changed = TRUE; + + /* Apply changes for the specified preference */ + prefs_apply(wlan_prefs); + + /* FREE MEMORY */ + /* free the WEP key string */ + for(i=0;ilist);i++) + { + g_free(g_list_nth(user_data->list,i)->data); + } + + /* free the (empty) list */ + g_list_free(user_data->list); + + /* free the user_data structure */ + g_free(user_data); + + airpcap_if_info_free(fake_info_if); + + return keys_in_list; +} + +/* + * Function used to save to the preference file the Decryption Keys. + */ +int +save_wlan_wireshark_wep_keys(GList* key_ls) +{ + GList* key_list = NULL; + guint keys_in_list,i; + keys_cb_data_t* user_data; + decryption_key_t* tmp_dk; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + keys_in_list = g_list_length(key_ls); + + key_list = key_ls; + + /* Fill the structure */ + user_data->list = key_list; + user_data->current_index = 0; + user_data->number_of_keys= keys_in_list; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, set_wep_key, (gpointer)user_data); + + /* Signal that we've changed things, and run the 802.11 dissector's + * callback */ + wlan_prefs->prefs_changed = TRUE; + + /* Apply changes for the specified preference */ + prefs_apply(wlan_prefs); + + /* FREE MEMORY */ + /* free the WEP key string */ + for(i=0;ilist);i++) + { + tmp_dk = (decryption_key_t*)g_list_nth(user_data->list,i)->data; + g_string_free(tmp_dk->key,TRUE); + if (tmp_dk->ssid != NULL) g_byte_array_free(tmp_dk->ssid,TRUE); + } + + /* free the (empty) list */ + g_list_free(user_data->list); + + /* free the user_data structure */ + g_free(user_data); + + return keys_in_list; +} + +/* + * Get an error message string for a CANT_GET_INTERFACE_LIST error from + * "get_airpcap_interface_list()". + */ +static gchar * +cant_get_airpcap_if_list_error_message(const char *err_str) +{ + return g_strdup_printf("Can't get list of Wireless interfaces: %s", err_str); +} + +/* + * Airpcap wrapper, used to store the current settings for the selected adapter + */ +gboolean +airpcap_if_store_cur_config_as_adapter_default(PAirpcapHandle ah) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapStoreCurConfigAsAdapterDefault(ah); +} + +/* + * Airpcap wrapper, used to open an airpcap adapter + */ +PAirpcapHandle +airpcap_if_open(gchar * name, gchar * err) +{ + if (!AirpcapLoaded) return NULL; + if (name == NULL) return NULL; + return g_PAirpcapOpen(name,err); +} + +/* + * Airpcap wrapper, used to close an airpcap adapter + */ +void +airpcap_if_close(PAirpcapHandle handle) +{ + if (!AirpcapLoaded) return; + g_PAirpcapClose(handle); +} + +/* + * Retrieve the state of the Airpcap DLL + */ +int +airpcap_get_dll_state(void) +{ + return AirpcapVersion; +} + +/* + * Airpcap wrapper, used to turn on the led of an airpcap adapter + */ +gboolean +airpcap_if_turn_led_on(PAirpcapHandle AdapterHandle, guint LedNumber) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapTurnLedOn(AdapterHandle,LedNumber); +} + +/* + * Airpcap wrapper, used to turn off the led of an airpcap adapter + */ +gboolean +airpcap_if_turn_led_off(PAirpcapHandle AdapterHandle, guint LedNumber) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapTurnLedOff(AdapterHandle,LedNumber); +} + +/* + * Airpcap wrapper, used to get the channel of an airpcap adapter + */ +gboolean +airpcap_if_get_device_channel(PAirpcapHandle ah, guint * ch) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapGetDeviceChannel(ah,ch); +} + +/* + * Airpcap wrapper, used to get the supported channels of an airpcap adapter + */ +gboolean +airpcap_if_get_device_supported_channels(PAirpcapHandle ah, AirpcapChannelInfo **cInfo, guint * nInfo) +{ + if (!AirpcapLoaded) return FALSE; + if (airpcap_get_dll_state() == AIRPCAP_DLL_OLD) { + *nInfo = num_legacy_channels; + *cInfo = (AirpcapChannelInfo*)&LegacyChannels; + + return TRUE; + } else if (airpcap_get_dll_state() == AIRPCAP_DLL_OK) { + return g_PAirpcapGetDeviceSupportedChannels(ah, cInfo, nInfo); + } + return FALSE; +} + +/* + * Airpcap wrapper, used to get the supported channels of an airpcap adapter + */ +Dot11Channel* +airpcap_if_get_device_supported_channels_array(PAirpcapHandle ah, guint * pNumSupportedChannels) +{ + AirpcapChannelInfo *chanInfo; + guint i=0, j=0, numInfo = 0; + + if (!AirpcapLoaded) + return NULL; + if (airpcap_if_get_device_supported_channels(ah, &chanInfo, &numInfo) == FALSE) + return NULL; + numSupportedChannels = 0; + + /* + * allocate a bigger array + */ + if (numInfo == 0) + return NULL; + + pSupportedChannels = (Dot11Channel *)g_malloc(numInfo * (sizeof *pSupportedChannels)); + + for (i = 0; i < numInfo; i++) + { + guint supportedChannel = G_MAXUINT; + + /* + * search if we have it already + */ + for (j = 0; j < numSupportedChannels; j++) + { + if (pSupportedChannels[j].Frequency == chanInfo[i].Frequency) + { + supportedChannel = j; + break; + } + } + + if (supportedChannel == G_MAXUINT) + { + /* + * not found, create a new item + */ + pSupportedChannels[numSupportedChannels].Frequency = chanInfo[i].Frequency; + + switch(chanInfo[i].ExtChannel) + { + case -1: + pSupportedChannels[numSupportedChannels].Flags = FLAG_CAN_BE_LOW; + break; + case +1: + pSupportedChannels[numSupportedChannels].Flags = FLAG_CAN_BE_HIGH; + break; + case 0: + default: + pSupportedChannels[numSupportedChannels].Flags = 0; + } + + /* + * Gather channel information + */ + + pSupportedChannels[numSupportedChannels].Flags |= + FREQ_IS_BG(pSupportedChannels[numSupportedChannels].Frequency) ? + FLAG_IS_BG_CHANNEL : FLAG_IS_A_CHANNEL; + pSupportedChannels[numSupportedChannels].Channel = + ieee80211_mhz_to_chan(pSupportedChannels[numSupportedChannels].Frequency); + numSupportedChannels++; + } + else + { + /* + * just update the ext channel flags + */ + switch(chanInfo[i].ExtChannel) + { + case -1: + pSupportedChannels[supportedChannel].Flags |= FLAG_CAN_BE_LOW; + break; + case +1: + pSupportedChannels[supportedChannel].Flags |= FLAG_CAN_BE_HIGH; + break; + case 0: + default: + break; + } + } + } + + if (numSupportedChannels < 1) + return NULL; + /* + * Now sort the list by frequency + */ + for (i = 0 ; i < numSupportedChannels - 1; i++) + { + for (j = i + 1; j < numSupportedChannels; j++) + { + if (pSupportedChannels[i].Frequency > pSupportedChannels[j].Frequency) + { + Dot11Channel temp = pSupportedChannels[i]; + pSupportedChannels[i] = pSupportedChannels[j]; + pSupportedChannels[j] = temp; + } + } + } + + *pNumSupportedChannels = numSupportedChannels; + return pSupportedChannels; +} + +/* + * Airpcap wrapper, used to set the channel of an airpcap adapter + */ +gboolean +airpcap_if_set_device_channel(PAirpcapHandle ah, guint ch) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapSetDeviceChannel(ah,ch); +} + +/* + * Airpcap wrapper, used to set the frequency of an airpcap adapter + */ +gboolean +airpcap_if_set_device_channel_ex(PAirpcapHandle ah, AirpcapChannelInfo ChannelInfo) +{ + if (!AirpcapLoaded) return FALSE; + if (airpcap_get_dll_state() == AIRPCAP_DLL_OLD){ + gint channel = 0; + channel = ieee80211_mhz_to_chan(ChannelInfo.Frequency); + + if (channel < 0){ + return FALSE; + } else { + return airpcap_if_set_device_channel(ah, channel); + } + } else if (airpcap_get_dll_state() == AIRPCAP_DLL_OK){ + return g_PAirpcapSetDeviceChannelEx (ah, ChannelInfo); + } + + return FALSE; +} + +/* + * Airpcap wrapper, used to get the frequency of an airpcap adapter + */ +gboolean +airpcap_if_get_device_channel_ex(PAirpcapHandle ah, PAirpcapChannelInfo pChannelInfo) +{ + if (!AirpcapLoaded) return FALSE; + + pChannelInfo->Frequency = 0; + pChannelInfo->ExtChannel = 0; + pChannelInfo->Reserved[0] = 0; + pChannelInfo->Reserved[1] = 0; + pChannelInfo->Reserved[2] = 0; + + if (airpcap_get_dll_state() == AIRPCAP_DLL_OLD){ + guint channel = 0; + guint chan_freq = 0; + + if (!airpcap_if_get_device_channel(ah, &channel)) return FALSE; + + chan_freq = ieee80211_chan_to_mhz(channel, TRUE); + if (chan_freq == 0) return FALSE; + pChannelInfo->Frequency = chan_freq; + + return TRUE; + } else if (airpcap_get_dll_state() == AIRPCAP_DLL_OK){ + return g_PAirpcapGetDeviceChannelEx (ah, pChannelInfo); + } + return FALSE; +} + +/* + * Airpcap wrapper, used to get the link type of an airpcap adapter + */ +gboolean +airpcap_if_get_link_type(PAirpcapHandle ah, PAirpcapLinkType lt) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapGetLinkType(ah,lt); +} + +/* + * Airpcap wrapper, used to set the link type of an airpcap adapter + */ +gboolean +airpcap_if_set_link_type(PAirpcapHandle ah, AirpcapLinkType lt) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapSetLinkType(ah,lt); +} + +/* + * Airpcap wrapper, used to get the fcs presence of an airpcap adapter + */ +gboolean +airpcap_if_get_fcs_presence(PAirpcapHandle ah, gboolean * fcs) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapGetFcsPresence(ah,fcs); +} + +/* + * Airpcap wrapper, used to set the fcs presence of an airpcap adapter + */ +gboolean +airpcap_if_set_fcs_presence(PAirpcapHandle ah, gboolean fcs) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapSetFcsPresence(ah,fcs); +} + +/* + * Airpcap wrapper, used to get the decryption enabling of an airpcap adapter + */ +gboolean +airpcap_if_get_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState PEnable) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapGetDecryptionState(ah,PEnable); +} + +/* + * Airpcap wrapper, used to set the decryption enabling of an airpcap adapter + */ +gboolean +airpcap_if_set_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState Enable) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapSetDecryptionState(ah,Enable); +} + +/* + * Airpcap wrapper, used to get the decryption enabling of an airpcap driver + */ +gboolean +airpcap_if_get_driver_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState PEnable) +{ + if (!AirpcapLoaded || (g_PAirpcapGetDriverDecryptionState==NULL)) return FALSE; + return g_PAirpcapGetDriverDecryptionState(ah,PEnable); +} + +/* + * Airpcap wrapper, used to set the decryption enabling of an airpcap driver + */ +gboolean +airpcap_if_set_driver_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState Enable) +{ + if (!AirpcapLoaded || (g_PAirpcapSetDriverDecryptionState==NULL)) return FALSE; + return g_PAirpcapSetDriverDecryptionState(ah,Enable); +} + +/* + * Airpcap wrapper, used to get the fcs validation of an airpcap adapter + */ +gboolean +airpcap_if_get_fcs_validation(PAirpcapHandle ah, PAirpcapValidationType val) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapGetFcsValidation(ah,val); +} + +/* + * Airpcap wrapper, used to set the fcs validation of an airpcap adapter + */ +gboolean +airpcap_if_set_fcs_validation(PAirpcapHandle ah, AirpcapValidationType val) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapSetFcsValidation(ah,val); +} + +/* + * Airpcap wrapper, used to save the settings for the selected_if + */ +gboolean +airpcap_if_set_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapSetDeviceKeys(AdapterHandle,KeysCollection); +} + +/* + * Airpcap wrapper, used to save the settings for the selected_if + */ +gboolean +airpcap_if_get_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize) +{ + if (!AirpcapLoaded) return FALSE; + return g_PAirpcapGetDeviceKeys(AdapterHandle,KeysCollection,PKeysCollectionSize); +} + +/* + * Airpcap wrapper, used to save the driver's set of keys + */ +gboolean +airpcap_if_set_driver_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection) +{ + if (!AirpcapLoaded || (g_PAirpcapSetDriverKeys==NULL)) return FALSE; + return g_PAirpcapSetDriverKeys(AdapterHandle,KeysCollection); +} + +/* + * Airpcap wrapper, used to load the driver's set of keys + */ +gboolean +airpcap_if_get_driver_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize) +{ + if (!AirpcapLoaded || (g_PAirpcapGetDriverKeys==NULL)) return FALSE; + return g_PAirpcapGetDriverKeys(AdapterHandle,KeysCollection,PKeysCollectionSize); +} + +/* + * This function will create a new airpcap_if_info_t using a name and a description + */ +airpcap_if_info_t * +airpcap_if_info_new(char *name, char *description) +{ + PAirpcapHandle ad; + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + + airpcap_if_info_t *if_info = NULL; + + /* Probably I have to switch on the leds!!! */ + ad = airpcap_if_open(name, ebuf); + if (ad) + { + if_info = (airpcap_if_info_t *)g_malloc0(sizeof (airpcap_if_info_t)); + if_info->name = g_strdup(name); + if (description == NULL){ + if_info->description = NULL; + }else{ + if_info->description = g_strdup(description); + } + + if_info->ip_addr = NULL; + if_info->loopback = FALSE; + airpcap_if_get_fcs_validation(ad,&(if_info->CrcValidationOn)); + airpcap_if_get_fcs_presence(ad,&(if_info->IsFcsPresent)); + airpcap_if_get_link_type(ad,&(if_info->linkType)); + airpcap_if_get_device_channel_ex(ad,&(if_info->channelInfo)); + if_info->pSupportedChannels = airpcap_if_get_device_supported_channels_array(ad, &(if_info->numSupportedChannels)); + airpcap_if_turn_led_on(ad, 0); + airpcap_if_get_decryption_state(ad, &(if_info->DecryptionOn)); + if_info->led = TRUE; + if_info->blinking = FALSE; + if_info->saved = TRUE; /* NO NEED TO BE SAVED */ + + /* get the keys, if everything is ok, close the adapter */ + if (airpcap_if_load_keys(ad,if_info)) + { + airpcap_if_close(ad); + } + } + return if_info; +} + +/* + * This function will create a new fake drivers' interface, to load global keys... + */ +airpcap_if_info_t* +airpcap_driver_fake_if_info_new(void) +{ + PAirpcapHandle ad; + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + + airpcap_if_info_t *if_info = NULL; + airpcap_if_info_t *fake_if_info = NULL; + + /* Maybe for some reason no airpcap adapter is found */ + if (airpcap_if_list == NULL) + return NULL; + + /* + * Retrieve the first AirPcap adapter available. If no interface is found, + * it is not possible to retrieve the driver's settings, so return NULL. + */ + if_info = (airpcap_if_info_t *)g_list_nth_data(airpcap_if_list,0); + if (if_info == NULL) + return NULL; + + /* Open the 'fake' adapter */ + ad = airpcap_if_open(if_info->name, ebuf); + if (ad) + { + fake_if_info = (airpcap_if_info_t *)g_malloc(sizeof (airpcap_if_info_t)); + fake_if_info->name = g_strdup(if_info->name); + fake_if_info->description = g_strdup(if_info->description); + fake_if_info->loopback = FALSE; + fake_if_info->ip_addr = NULL; + airpcap_if_get_driver_decryption_state(ad, &(fake_if_info->DecryptionOn)); + airpcap_if_get_fcs_validation(ad,&(fake_if_info->CrcValidationOn)); + airpcap_if_get_fcs_presence(ad,&(fake_if_info->IsFcsPresent)); + airpcap_if_get_link_type(ad,&(fake_if_info->linkType)); + airpcap_if_get_device_channel_ex(ad,&(fake_if_info->channelInfo)); + airpcap_if_turn_led_on(ad, 0); + fake_if_info->led = TRUE; + fake_if_info->blinking = FALSE; + fake_if_info->saved = TRUE; /* NO NEED TO BE SAVED */ + + /* get the keys, if everything is ok, close the adapter */ + if (airpcap_if_load_driver_keys(ad,fake_if_info)) + { + airpcap_if_close(ad); + } + } + + return fake_if_info; +} + +/* + * USED FOR DEBUG ONLY... PRINTS AN AirPcap ADAPTER STRUCTURE in a fancy way. + */ +void +airpcap_if_info_print(airpcap_if_info_t* if_info) +{ + guint i; + if (if_info == NULL) + { + g_print("\nWARNING : AirPcap Interface pointer is NULL!\n"); + return; + } + + g_print("\n----------------- AirPcap Interface \n"); + g_print(" NAME: %s\n",if_info->name); + g_print(" DESCRIPTION: %s\n",if_info->description); + g_print(" BLINKING: %s\n",if_info->blinking ? "TRUE" : "FALSE"); + g_print(" channelInfo.Frequency: %u\n",if_info->channelInfo.Frequency); + g_print(" channelInfo.ExtChannel: %d\n",if_info->channelInfo.ExtChannel); + g_print(" CRCVALIDATION: %s\n",if_info->CrcValidationOn ? "ON" : "OFF"); + g_print(" DECRYPTION: %s\n",if_info->DecryptionOn ? "ON" : "OFF"); + g_print(" IP ADDR: %s\n",if_info->ip_addr!=NULL ? "NOT NULL" : "NULL"); + g_print(" FCSPRESENT: %s\n",if_info->IsFcsPresent ? "TRUE" : "FALSE"); + g_print(" KEYSCOLLECTION: %s\n",if_info->keysCollection!=NULL ? "NOT NULL" : "NULL"); + g_print(" KEYSCOLLECTIONSIZE: %u\n",if_info->keysCollectionSize); + g_print(" LED: %s\n",if_info->led ? "ON" : "OFF"); + g_print(" LINKTYPE: %d\n",if_info->linkType); + g_print(" LOOPBACK: %s\n",if_info->loopback ? "YES" : "NO"); + g_print(" (GTK) TAG: %d\n",if_info->tag); + g_print("SUPPORTED CHANNELS POINTER: %p\n",if_info->pSupportedChannels); + g_print(" NUM SUPPORTED CHANNELS: %u\n",if_info->numSupportedChannels); + + for(i=0; i<(if_info->numSupportedChannels); i++){ + g_print("\n SUPPORTED CHANNEL #%u\n",i+1); + g_print(" CHANNEL: %u\n",if_info->pSupportedChannels[i].Channel); + g_print(" FREQUENCY: %u\n",if_info->pSupportedChannels[i].Frequency); + g_print(" FLAGS: %u\n",if_info->pSupportedChannels[i].Flags); + } + g_print("\n\n"); +} + +/* + * Function used to load the WEP keys for a selected interface + */ +gboolean +airpcap_if_load_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info) +{ + if (!if_info) return FALSE; + + if_info->keysCollectionSize = 0; + if_info->keysCollection = NULL; + + if (!airpcap_if_get_device_keys(ad, NULL, &(if_info->keysCollectionSize))) + { + if (if_info->keysCollectionSize == 0) + { + if_info->keysCollection = NULL; + airpcap_if_close(ad); + return FALSE; + } + + if_info->keysCollection = (PAirpcapKeysCollection)g_malloc(if_info->keysCollectionSize); + if (!if_info->keysCollection) + { + if_info->keysCollectionSize = 0; + if_info->keysCollection = NULL; + airpcap_if_close(ad); + return FALSE; + } + + airpcap_if_get_device_keys(ad, if_info->keysCollection, &(if_info->keysCollectionSize)); + return TRUE; + } + + airpcap_if_close(ad); + return FALSE; +} + +/* + * Function used to load the WEP keys for a selected interface + */ +gboolean +airpcap_if_load_driver_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info) +{ + if_info->keysCollectionSize = 0; + if_info->keysCollection = NULL; + + if (!airpcap_if_get_driver_keys(ad, NULL, &(if_info->keysCollectionSize))) + { + if (if_info->keysCollectionSize == 0) + { + if_info->keysCollection = NULL; + airpcap_if_close(ad); + return FALSE; + } + + if_info->keysCollection = (PAirpcapKeysCollection)g_malloc(if_info->keysCollectionSize); + if (!if_info->keysCollection) + { + if_info->keysCollectionSize = 0; + if_info->keysCollection = NULL; + airpcap_if_close(ad); + return FALSE; + } + + airpcap_if_get_driver_keys(ad, if_info->keysCollection, &(if_info->keysCollectionSize)); + return TRUE; + } + + airpcap_if_close(ad); + return FALSE; +} + +/* + * Function used to save the WEP keys for a selected interface + */ +void +airpcap_if_save_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info) +{ + if (!if_info || !AirpcapLoaded) return; + + if (if_info->keysCollection != NULL) + g_PAirpcapSetDeviceKeys(ad,if_info->keysCollection); +} + +/* + * Function used to save the WEP keys for a selected interface + */ +void +airpcap_if_save_driver_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info) +{ + if (if_info->keysCollection != NULL) + airpcap_if_set_driver_keys(ad,if_info->keysCollection); +} + +/* + * Callback used to free an instance of airpcap_if_info_t + */ +static void +free_airpcap_if_cb(gpointer data, gpointer user_data _U_) +{ + airpcap_if_info_t *if_info = (airpcap_if_info_t *)data; + + if (NULL == if_info) + return; + + if (if_info->name != NULL) + g_free(if_info->name); + + if (if_info->description != NULL) + g_free(if_info->description); + + /* XXX - FREE THE WEP KEY LIST HERE!!!*/ + if (if_info->keysCollection != NULL) + { + g_free(if_info->keysCollection); + if_info->keysCollection = NULL; + } + + if (if_info->ip_addr != NULL) + g_slist_free(if_info->ip_addr); + + g_free(if_info); +} + +/* + * Function used to free the airpcap interface list + */ +void +free_airpcap_interface_list(GList *if_list) +{ + g_list_foreach(if_list, free_airpcap_if_cb, NULL); + g_list_free(if_list); + if_list = NULL; +} + +/* + * This function will use the airpcap.dll to find all the airpcap devices. + * Will return null if no device is found. + */ +GList* +get_airpcap_interface_list(int *err, char **err_str) +{ + GList *il = NULL; + airpcap_if_info_t *if_info; + int n_adapts; + AirpcapDeviceDescription *devsList, *adListEntry; + char errbuf[AIRPCAP_ERRBUF_SIZE]; + + *err = 0; + + if (!AirpcapLoaded) + { + *err = AIRPCAP_NOT_LOADED; + return il; + } + + if (!g_PAirpcapGetDeviceList(&devsList, errbuf)) + { + /* No interfaces, return il = NULL; */ + *err = CANT_GET_AIRPCAP_INTERFACE_LIST; + if (err_str != NULL) + *err_str = cant_get_airpcap_if_list_error_message(errbuf); + return il; + } + + /* + * Count the adapters + */ + adListEntry = devsList; + n_adapts = 0; + while(adListEntry) + { + n_adapts++; + adListEntry = adListEntry->next; + } + + if (n_adapts == 0) + { + /* No interfaces, return il= NULL */ + g_PAirpcapFreeDeviceList(devsList); + *err = NO_AIRPCAP_INTERFACES_FOUND; + if (err_str != NULL) + *err_str = NULL; + return il; + } + + /* + * Insert the adapters in our list + */ + adListEntry = devsList; + while(adListEntry) + { + if_info = airpcap_if_info_new(adListEntry->Name, adListEntry->Description); + if (if_info != NULL){ + il = g_list_append(il, if_info); + } + + adListEntry = adListEntry->next; + } + + g_PAirpcapFreeDeviceList(devsList); + + return il; +} + +/* + * Used to retrieve the interface given the name + * (the name is used in AirpcapOpen) + */ +airpcap_if_info_t* get_airpcap_if_from_name(GList* if_list, const gchar* name) +{ + GList* curr; + airpcap_if_info_t* if_info; + + for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) { + if_info = (airpcap_if_info_t *)curr->data; + if (if_info && (g_ascii_strcasecmp(if_info->name, name) == 0)) { + return (if_info); + } + } + return (NULL); +} + +/* + * Returns the ASCII string of a key given the key bytes + */ +gchar* +airpcap_get_key_string(AirpcapKey key) +{ + unsigned int j = 0; + gchar *dst,*src; + + dst = NULL; + src = NULL; + + if (key.KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + if (key.KeyLen != 0) + { + /* Allocate the string used to store the ASCII representation of the WEP key */ + dst = (gchar*)g_malloc(sizeof(gchar)*WEP_KEY_MAX_CHAR_SIZE + 1); + /* Make sure that the first char is '\0' in order to make g_strlcat() work */ + dst[0]='\0'; + + for(j = 0; j < key.KeyLen; j++) + { + src = g_strdup_printf("%.2x", key.KeyData[j]); + /* + * XXX - use g_strconcat() or GStrings instead ??? + */ + g_strlcat(dst, src, WEP_KEY_MAX_CHAR_SIZE+1); + } + g_free(src); + } + } + else if (key.KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - Add code here */ + } + else if (key.KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - Add code here */ + } + else + { + /* XXX - Add code here */ + } + + return dst; +} + +/* + * Clear keys and decryption status for the specified interface + */ +void +airpcap_if_clear_decryption_settings(airpcap_if_info_t* info_if) +{ + if (info_if != NULL) + { + if (info_if->keysCollection != NULL) + { + g_free(info_if->keysCollection); + info_if->keysCollection = NULL; + } + + info_if->keysCollectionSize = 0; + + info_if->DecryptionOn = AIRPCAP_DECRYPTION_OFF; + info_if->saved = FALSE; + } +} + +/* + * Used to retrieve the two chars string from interface + */ +gchar* +airpcap_get_if_string_number(airpcap_if_info_t* if_info) +{ + gchar* number; + guint n; + int a; + + a = sscanf(if_info->name,AIRPCAP_DEVICE_NUMBER_EXTRACT_STRING,&n); + + /* If sscanf() returned 1, it means that has read a number, so interface is not "Any" + * Otherwise, check if it is the "Any" adapter... + */ + if (a == 0) + { + if (g_ascii_strcasecmp(if_info->name,AIRPCAP_DEVICE_ANY_EXTRACT_STRING)!=0) + number = g_strdup_printf("??"); + else + number = g_strdup_printf(AIRPCAP_CHANNEL_ANY_NAME); + } + else + { + number = g_strdup_printf("%.2u",n); + } + + return number; +} + +/* + * Used to retrieve the two chars string from interface + */ +gchar* +airpcap_get_if_string_number_from_description(gchar* description) +{ + gchar* number; + gchar* pointer; + + number = (gchar*)g_malloc(sizeof(gchar)*3); + + pointer = g_strrstr(description,"#\0"); + + number[0] = *(pointer+1); + number[1] = *(pointer+2); + number[2] = '\0'; + + return number; +} + +/* + * Returns the default airpcap interface of a list, NULL if list is empty + */ +airpcap_if_info_t* +airpcap_get_default_if(GList* airpcap_if_list_p) +{ + airpcap_if_info_t* if_info = NULL; + + if ((prefs.capture_device != NULL) && (*prefs.capture_device != '\0')) + { + if_info = get_airpcap_if_from_name(airpcap_if_list_p, + get_if_name(prefs.capture_device)); + } + return if_info; +} + +/* + * Load the configuration for the specified interface + */ +void +airpcap_load_selected_if_configuration(airpcap_if_info_t* if_info) +{ + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + PAirpcapHandle ad; + + if (if_info != NULL) + { + ad = airpcap_if_open(if_info->name, ebuf); + + if (ad) + { + /* Stop blinking (if it was blinking!)*/ + if (if_info->blinking) + { + /* Turn on the light (if it was off) */ + if (!(if_info->led)) airpcap_if_turn_led_on(ad, 0); + } + + /* Apply settings... */ + airpcap_if_get_device_channel_ex(ad,&(if_info->channelInfo)); + airpcap_if_get_fcs_validation(ad,&(if_info->CrcValidationOn)); + airpcap_if_get_fcs_presence(ad,&(if_info->IsFcsPresent)); + airpcap_if_get_link_type(ad,&(if_info->linkType)); + airpcap_if_get_decryption_state(ad, &(if_info->DecryptionOn)); + /* get the keys, if everything is ok, close the adapter */ + if (airpcap_if_load_keys(ad,if_info)) + airpcap_if_close(ad); + + if_info->saved = TRUE; + } + else + { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",if_info->description); + } + } +} + +/* + * Save the configuration for the specified interface + */ +void +airpcap_save_selected_if_configuration(airpcap_if_info_t* if_info) +{ + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + PAirpcapHandle ad; + + if (if_info != NULL) + { + ad = airpcap_if_open(if_info->name, ebuf); + + if (ad) + { + /* Stop blinking (if it was blinking!)*/ + if (if_info->blinking) + { + /* Turn on the light (if it was off) */ + if (!(if_info->led)) airpcap_if_turn_led_on(ad, 0); + } + + /* Apply settings... */ + airpcap_if_set_device_channel_ex(ad,if_info->channelInfo); + airpcap_if_set_fcs_validation(ad,if_info->CrcValidationOn); + airpcap_if_set_fcs_presence(ad,if_info->IsFcsPresent); + airpcap_if_set_link_type(ad,if_info->linkType); + airpcap_if_set_decryption_state(ad, if_info->DecryptionOn); + airpcap_if_save_keys(ad,if_info); + + /* ... and save them */ + if (!airpcap_if_store_cur_config_as_adapter_default(ad)) + { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save Wireless configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges."); + if_info->saved = FALSE; + airpcap_if_close(ad); + return; + } + + if_info->saved = TRUE; + airpcap_if_close(ad); + } + else + { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",if_info->description); + } + } +} + +/* + * Save the configuration for the specified interface + */ +void +airpcap_save_driver_if_configuration(airpcap_if_info_t* fake_if_info) +{ + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + PAirpcapHandle ad; + + if (fake_if_info != NULL) + { + ad = airpcap_if_open(fake_if_info->name, ebuf); + + if (ad) + { + /* Apply decryption settings... */ + airpcap_if_set_driver_decryption_state(ad, fake_if_info->DecryptionOn); + airpcap_if_save_driver_keys(ad,fake_if_info); + airpcap_if_close(ad); + } + else + { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, " Error in opening adapter for %s",fake_if_info->description); + } + } + + return; +} + +/* + * DECRYPTION KEYS FUNCTIONS + */ +/* + * This function is used for DEBUG POURPOSES ONLY!!! + */ +void +print_key_list(GList* key_list) +{ + gint n,i; + decryption_key_t* tmp; + + if (key_list == NULL) + { + g_print("\n\n******* KEY LIST NULL *******\n\n"); + return; + } + + n = g_list_length(key_list); + + g_print("\n\n********* KEY LIST **********\n\n"); + + g_print("NUMBER OF KEYS IN LIST : %d\n\n",n); + + for(i =0; i < n; i++) + { + g_print("[%d] :\n",i+1); + tmp = (decryption_key_t*)(g_list_nth_data(key_list,i)); + g_print("KEY : %s\n",tmp->key->str); + + g_print("BITS: %d\n",tmp->bits); + + if (tmp->type == AIRPDCAP_KEY_TYPE_WEP) + g_print("TYPE: %s\n",AIRPCAP_WEP_KEY_STRING); + else if (tmp->type == AIRPDCAP_KEY_TYPE_WPA_PWD) + g_print("TYPE: %s\n",AIRPCAP_WPA_PWD_KEY_STRING); + else if (tmp->type == AIRPDCAP_KEY_TYPE_WPA_PMK) + g_print("TYPE: %s\n",AIRPCAP_WPA_BIN_KEY_STRING); + else + g_print("TYPE: %s\n","???"); + + g_print("SSID: %s\n",(tmp->ssid != NULL) ? + format_text((guchar *)tmp->ssid->data, tmp->ssid->len) : "---"); + g_print("\n"); + } + + g_print("\n*****************************\n\n"); +} + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the given adapter... returns NULL if no keys are found. + */ +GList * +get_airpcap_device_keys(airpcap_if_info_t* info_if) +{ + /* tmp vars */ + char* tmp_key = NULL; + guint i,keys_in_list = 0; + + /* real vars*/ + decryption_key_t *new_key = NULL; + GList *key_list = NULL; + + /* Number of keys in key list */ + if (info_if->keysCollectionSize != 0) + keys_in_list = AirpcapKeysCollectionSizeToKeyCount(info_if->keysCollectionSize); + else + keys_in_list = 0; + + for(i=0; ikeysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + /* allocate memory for the new key item */ + new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t)); + + /* fill the fields */ + /* KEY */ + tmp_key = airpcap_get_key_string(info_if->keysCollection->Keys[i]); + new_key->key = g_string_new(tmp_key); + g_free(tmp_key); + + /* BITS */ + new_key->bits = (guint) new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an hexadecimal number) */ + + /* SSID not used in WEP keys */ + new_key->ssid = NULL; + + /* TYPE (WEP in this case) */ + new_key->type = info_if->keysCollection->Keys[i].KeyType; + + /* Append the new element in the list */ + key_list = g_list_append(key_list,(gpointer)new_key); + } + else if (info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - Not supported yet */ + } + else if (info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - Not supported yet */ + } + } + + return key_list; +} + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the global AirPcap driver... returns NULL if no keys are found. + */ +GList * +get_airpcap_driver_keys(void) +{ + /* tmp vars */ + char *tmp_key = NULL; + guint i,keys_in_list = 0; + + /* real vars*/ + decryption_key_t *new_key = NULL; + GList *key_list = NULL; + + /* + * To read the drivers general settings we need to create and use one airpcap adapter... + * The only way to do that is to instantiate a fake adapter, and then close it and delete it. + */ + airpcap_if_info_t* fake_info_if = NULL; + + /* Create the fake_info_if from the first adapter of the list */ + fake_info_if = airpcap_driver_fake_if_info_new(); + + if (fake_info_if == NULL) + return NULL; + + /* Number of keys in key list */ + if (fake_info_if->keysCollectionSize != 0) + keys_in_list = AirpcapKeysCollectionSizeToKeyCount(fake_info_if->keysCollectionSize); + else + keys_in_list = 0; + + for(i=0; ikeysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WEP) + { + /* allocate memory for the new key item */ + new_key = (decryption_key_t*)g_malloc(sizeof(decryption_key_t)); + + /* fill the fields */ + /* KEY */ + tmp_key = airpcap_get_key_string(fake_info_if->keysCollection->Keys[i]); + new_key->key = g_string_new(tmp_key); + if (tmp_key != NULL) g_free(tmp_key); + + /* BITS */ + new_key->bits = (guint) new_key->key->len *4; /* every char is 4 bits in WEP keys (it is an hexadecimal number) */ + + /* SSID not used in WEP keys */ + new_key->ssid = NULL; + + /* TYPE (WEP in this case) */ + new_key->type = fake_info_if->keysCollection->Keys[i].KeyType; + + /* Append the new element in the list */ + key_list = g_list_append(key_list,(gpointer)new_key); + } + else if (fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD) + { + /* XXX - Not supported yet */ + } + else if (fake_info_if->keysCollection->Keys[i].KeyType == AIRPDCAP_KEY_TYPE_WPA_PMK) + { + /* XXX - Not supported yet */ + } + } + + airpcap_if_info_free(fake_info_if); + + return key_list; +} + +/* + * Returns the list of the decryption keys specified for wireshark, NULL if + * no key is found + */ +GList * +get_wireshark_keys(void) +{ + keys_cb_data_t *wep_user_data = NULL; + + GList *final_list = NULL; + GList *wep_final_list = NULL; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Allocate a structure used to keep infos between the callbacks */ + wep_user_data = (keys_cb_data_t*)g_malloc(sizeof(keys_cb_data_t)); + + /* Fill the structure */ + wep_user_data->list = NULL; + wep_user_data->current_index = 0; + wep_user_data->number_of_keys= 0; /* Still unknown */ + + /* Run the callback on each 802.11 preference */ + /* XXX - Right now, only WEP keys will be loaded */ + prefs_pref_foreach(wlan_prefs, get_wep_key, (gpointer)wep_user_data); + + /* Copy the list field in the user data structure pointer into the final_list */ + wep_final_list = wep_user_data->list; + + /* XXX - Merge the three lists!!!!! */ + final_list = wep_final_list; + + /* free the wep_user_data structure */ + g_free(wep_user_data); + + return final_list; +} + +/* + * Merges two lists of keys and return a newly created GList. If a key is + * found multiple times, it will just appear once! + * list1 and list 2 pointer will have to be freed manually if needed!!! + * If the total number of keys exceeeds the maximum number allowed, + * exceeding keys will be discarded... + */ +GList * +merge_key_list(GList* list1, GList* list2) +{ + guint n1=0,n2=0; + guint i; + decryption_key_t *dk1=NULL, + *dk2=NULL, + *new_dk=NULL; + + GList* merged_list = NULL; + + if ( (list1 == NULL) && (list2 == NULL) ) + return NULL; + + if (list1 == NULL) + { + n2 = g_list_length(list2); + + for(i=0;ibits = dk2->bits; + new_dk->type = dk2->type; + new_dk->key = g_string_new(dk2->key->str); + new_dk->ssid = byte_array_dup(dk2->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + } + else if (list2 == NULL) + { + n1 = g_list_length(list1); + + for(i=0;ibits = dk1->bits; + new_dk->type = dk1->type; + new_dk->key = g_string_new(dk1->key->str); + new_dk->ssid = byte_array_dup(dk1->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + } + else + { + n1 = g_list_length(list1); + n2 = g_list_length(list2); + + /* Copy the whole list1 into merged_list */ + for(i=0;ibits = dk1->bits; + new_dk->type = dk1->type; + new_dk->key = g_string_new(dk1->key->str); + new_dk->ssid = byte_array_dup(dk1->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + + /* Look for keys that are present in list2 but aren't in list1 yet... + * Add them to merged_list + */ + for(i=0;ibits = dk2->bits; + new_dk->type = dk2->type; + new_dk->key = g_string_new(dk2->key->str); + new_dk->ssid = byte_array_dup(dk2->ssid); + + /* Check the total length of the merged list */ + if (g_list_length(merged_list) < MAX_ENCRYPTION_KEYS) + merged_list = g_list_append(merged_list,(gpointer)new_dk); + } + } + } + + return merged_list; +} + +/* + * Use this function to free a key list. + */ +void +free_key_list(GList *list) +{ + guint i,n; + decryption_key_t *curr_key; + + if (list == NULL) + return; + + n = g_list_length(list); + + for(i = 0; i < n; i++) + { + curr_key = (decryption_key_t*)g_list_nth_data(list,i); + + /* Free all the strings */ + if (curr_key->key != NULL) + g_string_free(curr_key->key, TRUE); + + if (curr_key->ssid != NULL) + g_byte_array_free(curr_key->ssid, TRUE); + + /* free the decryption_key_t structure*/ + g_free(curr_key); + curr_key = NULL; + } + + /* Free the list */ + g_list_free(list); + + return; +} + + +/* + * If the given key is contained in the list, returns TRUE. + * Returns FALSE otherwise. + */ +gboolean +key_is_in_list(decryption_key_t *dk,GList *list) +{ + guint i,n; + decryption_key_t *curr_key = NULL; + gboolean found = FALSE; + + if ( (list == NULL) || (dk == NULL) ) + return FALSE; + + n = g_list_length(list); + + if (n < 1) + return FALSE; + + for(i = 0; i < n; i++) + { + curr_key = (decryption_key_t*)g_list_nth_data(list,i); + if (keys_are_equals(dk,curr_key)) + found = TRUE; + } + + return found; +} + +/* + * Returns TRUE if keys are equals, FALSE otherwise + */ +gboolean +keys_are_equals(decryption_key_t *k1,decryption_key_t *k2) +{ + + if ((k1==NULL) || (k2==NULL)) + return FALSE; + + /* XXX - Remove this check when we will have the WPA/WPA2 decryption in the Driver! */ + /** if ( (k1->type == AIRPDCAP_KEY_TYPE_WPA_PWD) || (k2->type == AIRPDCAP_KEY_TYPE_WPA_PWD) || (k1->type == AIRPDCAP_KEY_TYPE_WPA_PMK) || (k2->type == AIRPDCAP_KEY_TYPE_WPA_PMK) ) **/ + /** return TRUE; **/ + + if (g_string_equal(k1->key,k2->key) && + (k1->bits == k2->bits) && /* If the previous is TRUE, this must be TRUE as well */ + (k1->type == k2->type)) + { + /* Check the ssid... if the key type is WEP, the two fields should be NULL */ + if ((k1->ssid == NULL) && (k2->ssid == NULL)) + return TRUE; + + /* If they are not null, they must share the same ssid */ + return byte_array_equal(k1->ssid,k2->ssid); + } + + /* Some field is not equal ... */ + return FALSE; +} + +/* + * Tests if two collection of keys are equal or not, to be considered equals, they have to + * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will + * return TRUE) + */ +gboolean +key_lists_are_equal(GList* list1, GList* list2) +{ + guint n1 = 0,n2=0; + /* XXX - Remove */ + guint wep_n1 = 0,wep_n2=0; + GList *wep_list1 = NULL; + GList *wep_list2 = NULL; + /* XXX - END*/ + guint i/*,j*/; + decryption_key_t *dk1=NULL,*dk2=NULL; + + n1 = g_list_length(list1); + n2 = g_list_length(list2); + + /* + * XXX - START : Retrieve the aublists of WEP keys!!! This is needed only 'till Driver WPA decryption + * is implemented. + */ + for(i=0;itype == AIRPDCAP_KEY_TYPE_WEP) + { + wep_list1 = g_list_append(wep_list1,(gpointer)dk1); + wep_n1++; + } + } + for(i=0;itype == AIRPDCAP_KEY_TYPE_WEP) + { + wep_list2 = g_list_append(wep_list2,(gpointer)dk2); + wep_n2++; + } + } + + /* + * XXX - END : Remove from START to END when the WPA/WPA2 decryption will be implemented in + * the Driver + */ + + /* + * Commented, because in the new AirPcap version all the keys will be saved + * into the driver, and all the keys for every specific adapter will be + * removed. This means that this check will always fail... and the user will + * always be asked what to do... and it doesn't make much sense. + */ + /* if (n1 != n2) return FALSE; */ + if (wep_n1 != wep_n2) return FALSE; + + n2 = wep_n2; + + /*for(i=0;ikey,dk2->key)) return FALSE; + }*/ + for(i=0;iname, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL) + { + number = *pref->varp.boolp; + + if (number) *is_on = TRUE; + else *is_on = FALSE; + + return 1; + } + return 0; +} + +/* + * Returns TRUE if the Wireshark decryption is active, false otherwise + * XXX - Should we just add a routine to packet-ieee80211.c to grab this directly? + */ +gboolean +wireshark_decryption_on(void) +{ + gboolean is_on; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, test_if_on, (gpointer)&is_on); + + return is_on; +} + +/* + * Returns TRUE if the AirPcap decryption for the current adapter is active, false otherwise + */ +gboolean +airpcap_decryption_on(void) +{ + gboolean is_on = FALSE; + + airpcap_if_info_t* fake_if_info = NULL; + + fake_if_info = airpcap_driver_fake_if_info_new(); + + if (fake_if_info != NULL) + { + if (fake_if_info->DecryptionOn == AIRPCAP_DECRYPTION_ON) + is_on = TRUE; + else if (fake_if_info->DecryptionOn == AIRPCAP_DECRYPTION_OFF) + is_on = FALSE; + } + + airpcap_if_info_free(fake_if_info); + + return is_on; +} + +/* + * Free an instance of airpcap_if_info_t + */ +void +airpcap_if_info_free(airpcap_if_info_t *if_info) +{ + if (if_info != NULL) + { + if (if_info->name != NULL) + g_free(if_info->name); + + if (if_info->description != NULL) + g_free(if_info->description); + + if (if_info->keysCollection != NULL) + { + g_free(if_info->keysCollection); + if_info->keysCollection = NULL; + } + + if (if_info->ip_addr != NULL) + { + g_slist_free(if_info->ip_addr); + if_info->ip_addr = NULL; + } + + if (if_info != NULL) + { + g_free(if_info); + if_info = NULL; + } + } +} + +static guint +set_on_off(pref_t *pref, gpointer ud) +{ + gboolean *is_on; + + /* Retrieve user data info */ + is_on = (gboolean*)ud; + + if (g_ascii_strncasecmp(pref->name, "enable_decryption", 17) == 0 && pref->type == PREF_BOOL) + { + + if (*is_on) + *pref->varp.boolp = TRUE; + else + *pref->varp.boolp = FALSE; + + return 1; + } + return 0; +} + +/* + * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise. + */ +void +set_wireshark_decryption(gboolean on_off) +{ + gboolean is_on; + + is_on = on_off; + + /* Retrieve the wlan preferences */ + wlan_prefs = prefs_find_module("wlan"); + + /* Run the callback on each 802.11 preference */ + prefs_pref_foreach(wlan_prefs, set_on_off, (gpointer)&is_on); + + /* + * Signal that we've changed things, and run the 802.11 dissector's + * callback + */ + wlan_prefs->prefs_changed = TRUE; + + prefs_apply(wlan_prefs); +} + +/* + * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise. + */ +gboolean +set_airpcap_decryption(gboolean on_off) +{ + /* We need to directly access the .dll functions here... */ + gchar ebuf[AIRPCAP_ERRBUF_SIZE]; + PAirpcapHandle ad,ad_driver; + + gboolean success = TRUE; + + gint n = 0; + gint i = 0; + airpcap_if_info_t* curr_if = NULL; + airpcap_if_info_t* fake_if_info = NULL; + + fake_if_info = airpcap_driver_fake_if_info_new(); + + if (fake_if_info == NULL) + /* We apparently don't have any adapters installed. + * This isn't a failure, so return TRUE + */ + return TRUE; + + /* Set the driver decryption */ + ad_driver = airpcap_if_open(fake_if_info->name, ebuf); + if (ad_driver) + { + if (on_off) + airpcap_if_set_driver_decryption_state(ad_driver,AIRPCAP_DECRYPTION_ON); + else + airpcap_if_set_driver_decryption_state(ad_driver,AIRPCAP_DECRYPTION_OFF); + + airpcap_if_close(ad_driver); + } + + airpcap_if_info_free(fake_if_info); + + n = g_list_length(airpcap_if_list); + + /* Set to FALSE the decryption for all the adapters */ + /* Apply this change to all the adapters !!! */ + for(i = 0; i < n; i++) + { + curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i); + + if (curr_if != NULL) + { + ad = airpcap_if_open(curr_if->name, ebuf); + if (ad) + { + curr_if->DecryptionOn = AIRPCAP_DECRYPTION_OFF; + airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn); + /* Save configuration for the curr_if */ + if (!airpcap_if_store_cur_config_as_adapter_default(ad)) + { + success = FALSE; + } + airpcap_if_close(ad); + } + } + } + + return success; +} + + +/* DYNAMIC LIBRARY LOADER */ +/* + * Used to dynamically load the airpcap library in order link it only when + * it's present on the system + */ +int load_airpcap(void) +{ +#ifdef _WIN32 + gboolean base_functions = TRUE; + gboolean eleven_n_functions = TRUE; + + if ((AirpcapLib = ws_load_library("airpcap.dll")) == NULL) + { + /* Report the error but go on */ + AirpcapVersion = AIRPCAP_DLL_NOT_FOUND; + return AirpcapVersion; + } + else + { + if ((g_PAirpcapGetLastError = (AirpcapGetLastErrorHandler) GetProcAddress(AirpcapLib, "AirpcapGetLastError")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetDeviceList = (AirpcapGetDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceList")) == NULL) base_functions = FALSE; + if ((g_PAirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) GetProcAddress(AirpcapLib, "AirpcapFreeDeviceList")) == NULL) base_functions = FALSE; + if ((g_PAirpcapOpen = (AirpcapOpenHandler) GetProcAddress(AirpcapLib, "AirpcapOpen")) == NULL) base_functions = FALSE; + if ((g_PAirpcapClose = (AirpcapCloseHandler) GetProcAddress(AirpcapLib, "AirpcapClose")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetLinkType = (AirpcapGetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapGetLinkType")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetLinkType = (AirpcapSetLinkTypeHandler) GetProcAddress(AirpcapLib, "AirpcapSetLinkType")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) GetProcAddress(AirpcapLib, "AirpcapSetKernelBuffer")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetFilter = (AirpcapSetFilterHandler) GetProcAddress(AirpcapLib, "AirpcapSetFilter")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetMacAddress = (AirpcapGetMacAddressHandler) GetProcAddress(AirpcapLib, "AirpcapGetMacAddress")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) GetProcAddress(AirpcapLib, "AirpcapSetMinToCopy")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetReadEvent = (AirpcapGetReadEventHandler) GetProcAddress(AirpcapLib, "AirpcapGetReadEvent")) == NULL) base_functions = FALSE; + if ((g_PAirpcapRead = (AirpcapReadHandler) GetProcAddress(AirpcapLib, "AirpcapRead")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetStats = (AirpcapGetStatsHandler) GetProcAddress(AirpcapLib, "AirpcapGetStats")) == NULL) base_functions = FALSE; + if ((g_PAirpcapTurnLedOn = (AirpcapTurnLedOnHandler) GetProcAddress(AirpcapLib, "AirpcapTurnLedOn")) == NULL) base_functions = FALSE; + if ((g_PAirpcapTurnLedOff = (AirpcapTurnLedOffHandler) GetProcAddress(AirpcapLib, "AirpcapTurnLedOff")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetDeviceChannel = (AirpcapGetDeviceChannelHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceChannel")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetDeviceChannel = (AirpcapSetDeviceChannelHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceChannel")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetFcsPresence = (AirpcapGetFcsPresenceHandler) GetProcAddress(AirpcapLib, "AirpcapGetFcsPresence")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetFcsPresence = (AirpcapSetFcsPresenceHandler) GetProcAddress(AirpcapLib, "AirpcapSetFcsPresence")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetFcsValidation = (AirpcapGetFcsValidationHandler) GetProcAddress(AirpcapLib, "AirpcapGetFcsValidation")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetFcsValidation = (AirpcapSetFcsValidationHandler) GetProcAddress(AirpcapLib, "AirpcapSetFcsValidation")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetDeviceKeys = (AirpcapGetDeviceKeysHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceKeys")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetDeviceKeys = (AirpcapSetDeviceKeysHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceKeys")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetDecryptionState = (AirpcapGetDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapGetDecryptionState")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetDecryptionState = (AirpcapSetDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapSetDecryptionState")) == NULL) base_functions = FALSE; + if ((g_PAirpcapStoreCurConfigAsAdapterDefault = (AirpcapStoreCurConfigAsAdapterDefaultHandler) GetProcAddress(AirpcapLib, "AirpcapStoreCurConfigAsAdapterDefault")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetVersion = (AirpcapGetVersionHandler) GetProcAddress(AirpcapLib, "AirpcapGetVersion")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetDriverDecryptionState = (AirpcapGetDriverDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapGetDriverDecryptionState")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetDriverDecryptionState = (AirpcapSetDriverDecryptionStateHandler) GetProcAddress(AirpcapLib, "AirpcapSetDriverDecryptionState")) == NULL) base_functions = FALSE; + if ((g_PAirpcapGetDriverKeys = (AirpcapGetDriverKeysHandler) GetProcAddress(AirpcapLib, "AirpcapGetDriverKeys")) == NULL) base_functions = FALSE; + if ((g_PAirpcapSetDriverKeys = (AirpcapSetDriverKeysHandler) GetProcAddress(AirpcapLib, "AirpcapSetDriverKeys")) == NULL) base_functions = FALSE; + + /* TEST IF AIRPCAP SUPPORTS 11N */ + if ((g_PAirpcapSetDeviceChannelEx = (AirpcapSetDeviceChannelExHandler) GetProcAddress(AirpcapLib, "AirpcapSetDeviceChannelEx")) == NULL) eleven_n_functions = FALSE; + if ((g_PAirpcapGetDeviceChannelEx = (AirpcapGetDeviceChannelExHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceChannelEx")) == NULL) eleven_n_functions = FALSE; + if ((g_PAirpcapGetDeviceSupportedChannels = (AirpcapGetDeviceSupportedChannelsHandler) GetProcAddress(AirpcapLib, "AirpcapGetDeviceSupportedChannels")) == NULL) eleven_n_functions = FALSE; + + if (base_functions && eleven_n_functions){ + AirpcapLoaded = TRUE; + AirpcapVersion = AIRPCAP_DLL_OK; + } else if (base_functions){ + AirpcapLoaded = TRUE; + AirpcapVersion = AIRPCAP_DLL_OLD; + return AIRPCAP_DLL_OK; + }else{ + AirpcapLoaded = FALSE; + AirpcapVersion = AIRPCAP_DLL_ERROR; + } + } + return AirpcapVersion; +#else /* _WIN32 */ + return AIRPCAP_DLL_NOT_FOUND; +#endif /* _WIN32 */ +} + +/* + * Append the version of AirPcap with which we were compiled to a GString. + */ +void +get_compiled_airpcap_version(GString *str) +{ + g_string_append(str, "with AirPcap"); +} + +/* + * Append the version of AirPcap with which we we're running to a GString. + */ +void +get_runtime_airpcap_version(GString *str) +{ + guint vmaj, vmin, vrev, build; + + /* See if the DLL has been loaded successfully. Bail if it hasn't */ + if (AirpcapLoaded == FALSE) { + g_string_append(str, "without AirPcap"); + return; + } + + g_PAirpcapGetVersion(&vmaj, &vmin, &vrev, &build); + g_string_append_printf(str, "with AirPcap %d.%d.%d build %d", vmaj, vmin, + vrev, build); +} +#endif /* HAVE_AIRPCAP */ + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/caputils/airpcap_loader.h b/caputils/airpcap_loader.h new file mode 100644 index 0000000000..929604f082 --- /dev/null +++ b/caputils/airpcap_loader.h @@ -0,0 +1,560 @@ +/* airpcap_loader.h + * Declarations of routines for the "About" dialog + * + * Giorgio Tino + * Copyright (c) CACE Technologies, LLC 2006 + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AIRPCAP_LOADER_H__ +#define __AIRPCAP_LOADER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error values from "get_airpcap_interface_list()". */ +#define CANT_GET_AIRPCAP_INTERFACE_LIST 0 /* error getting list */ +#define NO_AIRPCAP_INTERFACES_FOUND 1 /* list is empty */ +#define AIRPCAP_NOT_LOADED 2 /* Airpcap DLL not loaded */ + +#define AIRPCAP_CHANNEL_ANY_NAME "ANY" + +#define AIRPCAP_WEP_KEY_STRING "WEP" +/* + * XXX - WPA_PWD is the passphrase+ssid and WPA-PSK is the hexadecimal key + */ +#define AIRPCAP_WPA_PWD_KEY_STRING "WPA-PWD" +#define AIRPCAP_WPA_BIN_KEY_STRING "WPA-PSK" + +#define AIRPCAP_DLL_OK 0 +#define AIRPCAP_DLL_OLD 1 +#define AIRPCAP_DLL_ERROR 2 +#define AIRPCAP_DLL_NOT_FOUND 3 + +typedef gchar * (*AirpcapGetLastErrorHandler)(PAirpcapHandle AdapterHandle); +typedef gboolean (*AirpcapGetDeviceListHandler)(PAirpcapDeviceDescription *PPAllDevs, gchar * Ebuf); +typedef void (*AirpcapFreeDeviceListHandler)(PAirpcapDeviceDescription PAllDevs); +typedef PAirpcapHandle (*AirpcapOpenHandler)(gchar * DeviceName, gchar * Ebuf); +typedef void (*AirpcapCloseHandler)(PAirpcapHandle AdapterHandle); +typedef gboolean (*AirpcapGetLinkTypeHandler)(PAirpcapHandle AdapterHandle, PAirpcapLinkType PLinkType); +typedef gboolean (*AirpcapSetLinkTypeHandler)(PAirpcapHandle AdapterHandle, AirpcapLinkType NewLinkType); +typedef gboolean (*AirpcapSetKernelBufferHandler)(PAirpcapHandle AdapterHandle, guint BufferSize); +typedef gboolean (*AirpcapSetFilterHandler)(PAirpcapHandle AdapterHandle, void * Instructions, guint Len); +typedef gboolean (*AirpcapGetMacAddressHandler)(PAirpcapHandle AdapterHandle, PAirpcapMacAddress PMacAddress); +typedef gboolean (*AirpcapSetMinToCopyHandler)(PAirpcapHandle AdapterHandle, guint MinToCopy); +typedef gboolean (*AirpcapGetReadEventHandler)(PAirpcapHandle AdapterHandle, void *** PReadEvent); +typedef gboolean (*AirpcapReadHandler)(PAirpcapHandle AdapterHandle, guint8 * Buffer, guint BufSize, guint * PReceievedBytes); +typedef gboolean (*AirpcapGetStatsHandler)(PAirpcapHandle AdapterHandle, PAirpcapStats PStats); +typedef gboolean (*AirpcapTurnLedOnHandler)(PAirpcapHandle AdapterHandle, guint LedNumber); +typedef gboolean (*AirpcapTurnLedOffHandler)(PAirpcapHandle AdapterHandle, guint LedNumber); +typedef gboolean (*AirpcapSetDeviceChannelHandler)(PAirpcapHandle AdapterHandle, guint Channel); +typedef gboolean (*AirpcapGetDeviceChannelHandler)(PAirpcapHandle AdapterHandle, guint * PChannel); +typedef gboolean (*AirpcapSetFcsPresenceHandler)(PAirpcapHandle AdapterHandle, gboolean IsFcsPresent); +typedef gboolean (*AirpcapGetFcsPresenceHandler)(PAirpcapHandle AdapterHandle, gboolean * PIsFcsPresent); +typedef gboolean (*AirpcapSetFcsValidationHandler)(PAirpcapHandle AdapterHandle, AirpcapValidationType ValidationType); +typedef gboolean (*AirpcapGetFcsValidationHandler)(PAirpcapHandle AdapterHandle, PAirpcapValidationType PValidationType); +typedef gboolean (*AirpcapSetDeviceKeysHandler)(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection); +typedef gboolean (*AirpcapGetDeviceKeysHandler)(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize); +typedef gboolean (*AirpcapSetDriverKeysHandler)(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection); +typedef gboolean (*AirpcapGetDriverKeysHandler)(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize); +typedef gboolean (*AirpcapSetDecryptionStateHandler)(PAirpcapHandle AdapterHandle, AirpcapDecryptionState Enable); +typedef gboolean (*AirpcapGetDecryptionStateHandler)(PAirpcapHandle AdapterHandle, PAirpcapDecryptionState PEnable); +typedef gboolean (*AirpcapSetDriverDecryptionStateHandler)(PAirpcapHandle AdapterHandle, AirpcapDecryptionState Enable); +typedef gboolean (*AirpcapGetDriverDecryptionStateHandler)(PAirpcapHandle AdapterHandle, PAirpcapDecryptionState PEnable); +typedef gboolean (*AirpcapStoreCurConfigAsAdapterDefaultHandler)(PAirpcapHandle AdapterHandle); +typedef void (*AirpcapGetVersionHandler)(guint * VersionMajor, guint * VersionMinor, guint * VersionRev, guint * VersionBuild); +typedef gboolean (*AirpcapSetDeviceChannelExHandler)(PAirpcapHandle AdapterHandle, AirpcapChannelInfo ChannelInfo); +typedef gboolean (*AirpcapGetDeviceChannelExHandler)(PAirpcapHandle AdapterHandle, PAirpcapChannelInfo PChannelInfo); +typedef gboolean (*AirpcapGetDeviceSupportedChannelsHandler)(PAirpcapHandle AdapterHandle, AirpcapChannelInfo **ppChannelInfo, guint32 * pNumChannelInfo); + +#define FLAG_CAN_BE_LOW 0x00000001 +#define FLAG_CAN_BE_HIGH 0x00000002 +#define FLAG_IS_BG_CHANNEL 0x00000004 +#define FLAG_IS_A_CHANNEL 0x00000008 + +typedef struct _Dot11Channel +{ + guint Channel; + guint32 Frequency; + guint32 Flags; +} Dot11Channel; + +/* + * The list of interfaces returned by "get_airpcap_interface_list()" is + * a list of these structures. + */ +typedef struct { + char *name; /* e.g. "eth0" */ + char *description; /* from OS, e.g. "Local Area Connection" or NULL */ + GSList *ip_addr; /* containing address values of if_addr_t */ + gboolean loopback; /* TRUE if loopback, FALSE otherwise */ + AirpcapLinkType linkType; /* The link layer type */ + AirpcapChannelInfo channelInfo; /* Channel Information */ + gboolean IsFcsPresent; /* Include 802.11 CRC in frames */ + AirpcapValidationType CrcValidationOn; /* Capture Frames with Wrong CRC */ + AirpcapDecryptionState DecryptionOn; /* TRUE if decryption is on, FALSE otherwise */ + PAirpcapKeysCollection keysCollection; /* WEP Key collection for the adapter */ + guint keysCollectionSize; /* Size of the key collection */ + gboolean blinking; /* TRUE if is blinkng, FALSE otherwise */ + gboolean led; /* TRUE if on, FALSE if off */ + gboolean saved; /* TRUE if current configuration has been saved, FALSE otherwise */ + gint tag; /* int for the gtk blinking callback */ + Dot11Channel *pSupportedChannels; + guint32 numSupportedChannels; +} airpcap_if_info_t; + +/* + * Struct used to store infos to pass to the preferences manager callbacks + */ +typedef struct { + GList *list; + int current_index; + int number_of_keys; +} keys_cb_data_t; + +/* Airpcap interface list */ +extern GList *airpcap_if_list; + +/* Airpcap current selected interface */ +extern airpcap_if_info_t *airpcap_if_selected; + +/* Airpcap current active interface */ +extern airpcap_if_info_t *airpcap_if_active; + +/* WLAN preferences pointer */ +/*extern module_t *wlan_prefs; - TODO: What is this?? */ + +/* + * Function used to read the Decryption Keys from the preferences and store them + * properly into the airpcap adapter. + */ +gboolean +load_wlan_driver_wep_keys(void); + +/* + * Function used to save to the prefereces file the Decryption Keys. + */ +gboolean +save_wlan_wep_keys(airpcap_if_info_t* info_if); + +/* + * This function will tell the airpcap driver the key list to use + * This will be stored into the registry... + */ +gboolean +write_wlan_wep_keys_to_registry(airpcap_if_info_t* info_if, GList* key_list); + +/* Returs TRUE if the WEP key is valid, false otherwise */ +gboolean +wep_key_is_valid(char* key); + +/* + * USED FOR DEBUG ONLY... PRINTS AN AirPcap ADAPTER STRUCTURE in a fancy way. + */ +void +airpcap_if_info_print(airpcap_if_info_t* if_info); + +/* + * Used to retrieve the two chars string from interface + */ +gchar* +airpcap_get_if_string_number_from_description(gchar* description); + +/* + * Function used to free the airpcap interface list + */ +void +free_airpcap_interface_list(GList *if_list); + +/* + * Used to retrieve the interface given the name + * (the name is used in AirpcapOpen) + */ +airpcap_if_info_t* get_airpcap_if_from_name(GList* if_list, const gchar* name); + +/* + * Airpcap wrapper, used to store the current settings for the selected adapter + */ +gboolean +airpcap_if_store_cur_config_as_adapter_default(PAirpcapHandle ah); + +/* + * Function used to load the WEP keys for a selected interface + */ +gboolean +airpcap_if_load_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info); + +/* + * Function used to load the WEP keys from the global driver list + */ +gboolean +airpcap_if_load_driver_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info); + +/* + * Function used to save the WEP keys for a selected interface + */ +void +airpcap_if_save_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info); + +/* + * Function used to save the WEP keys for a selected interface + */ +void +airpcap_if_save_driver_keys(PAirpcapHandle ad, airpcap_if_info_t *if_info); + +/* + * Airpcap wrapper, used to get the fcs validation of an airpcap adapter + */ +gboolean +airpcap_if_get_fcs_validation(PAirpcapHandle ah, PAirpcapValidationType val); + +/* + * Airpcap wrapper, used to set the fcs validation of an airpcap adapter + */ +gboolean +airpcap_if_set_fcs_validation(PAirpcapHandle ah, AirpcapValidationType val); + +/* + * Airpcap wrapper, used to get the decryption enabling of an airpcap adapter + */ +gboolean +airpcap_if_get_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState val); + +/* + * Airpcap wrapper, used to set the decryption enabling of an airpcap adapter + */ +gboolean +airpcap_if_set_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState val); + +/* + * Airpcap wrapper, used to get the fcs presence of an airpcap adapter + */ +gboolean +airpcap_if_get_fcs_presence(PAirpcapHandle ah, gboolean * ch); + +/* + * Airpcap wrapper, used to set the fcs presence of an airpcap adapter + */ +gboolean +airpcap_if_set_fcs_presence(PAirpcapHandle ah, gboolean ch); + +/* + * Airpcap wrapper, used to get the link type of an airpcap adapter + */ +gboolean +airpcap_if_get_link_type(PAirpcapHandle ah, PAirpcapLinkType lt); + +/* + * Airpcap wrapper, used to set the link type of an airpcap adapter + */ +gboolean +airpcap_if_set_link_type(PAirpcapHandle ah, AirpcapLinkType lt); + +/* + * Airpcap wrapper, used to get the channel of an airpcap adapter + */ +gboolean +airpcap_if_get_device_channel(PAirpcapHandle ah, guint * ch); + +/* + * Airpcap wrapper, get the channels supported by the adapter + */ +gboolean +airpcap_if_get_device_supported_channels(PAirpcapHandle ah, AirpcapChannelInfo **cInfo, guint32 * nInfo); + +/* + * Airpcap wrapper, get supported channels formatted into an array + */ +Dot11Channel* +airpcap_if_get_device_supported_channels_array(PAirpcapHandle ah, guint32 * pNumSupportedChannels); + +/* + * Airpcap wrapper, used to set the channel of an airpcap adapter + */ +gboolean +airpcap_if_set_device_channel(PAirpcapHandle ah, guint ch); + +/* + * Airpcap wrapper, used to get the frequency of an airpcap adapter + */ +gboolean +airpcap_if_get_device_channel_ex(PAirpcapHandle ah, PAirpcapChannelInfo pChannelInfo); + +/* + * Airpcap wrapper, used to set the frequency of an airpcap adapter + */ +gboolean +airpcap_if_set_device_channel_ex(PAirpcapHandle ah, AirpcapChannelInfo ChannelInfo); + +/* + * Airpcap wrapper, used to open an airpcap adapter + */ +PAirpcapHandle airpcap_if_open(gchar * name, gchar * err); + +/* + * Airpcap wrapper, used to close an airpcap adapter + */ +void airpcap_if_close(PAirpcapHandle handle); + +/* + * Retrieve the state of the Airpcap DLL + */ +int +airpcap_get_dll_state(void); + +/* + * Airpcap wrapper, used to turn on the led of an airpcap adapter + */ +gboolean airpcap_if_turn_led_on(PAirpcapHandle AdapterHandle, guint LedNumber); + +/* + * Airpcap wrapper, used to turn off the led of an airpcap adapter + */ +gboolean airpcap_if_turn_led_off(PAirpcapHandle AdapterHandle, guint LedNumber); + +/* + * This function will create a new airpcap_if_info_t using a name and a description + */ +airpcap_if_info_t* airpcap_if_info_new(char *name, char *description); + +/* + * This function will create a new fake drivers' interface, to load global keys... + */ +airpcap_if_info_t* airpcap_driver_fake_if_info_new(void); + +/* + * Used to dinamically load the airpcap library in order link it only when + * it's present on the system. + */ +int load_airpcap(void); + +/* + * This function will use the airpcap.dll to find all the airpcap devices. + * Will return null if no device is found. + */ +GList* +get_airpcap_interface_list(int *err, char **err_str); + +/* + * Returns the ASCII string of a key given the key bites + */ +gchar* +airpcap_get_key_string(AirpcapKey key); + +/* + * Load the configuration for the specified interface + */ +void +airpcap_load_selected_if_configuration(airpcap_if_info_t* if_info); + +/* + * Save the configuration for the specified interface + */ +void +airpcap_save_selected_if_configuration(airpcap_if_info_t* if_info); + +/* + * Used to retrieve the two chars string from interface description + */ +gchar* +airpcap_get_if_string_number(airpcap_if_info_t* if_info); + +/* + * Returns the default airpcap interface of a list, NULL if list is empty + */ +airpcap_if_info_t* +airpcap_get_default_if(GList* airpcap_if_list); + +/* + * Airpcap wrapper, used to save the settings for the selected_if + */ +gboolean +airpcap_if_set_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection); + +/* + * Airpcap wrapper, used to save the settings for the selected_if + */ +gboolean +airpcap_if_get_device_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize); + +/* + * Airpcap wrapper, used to save the settings for the selected_if + */ +gboolean +airpcap_if_set_driver_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection); + +/* + * Airpcap wrapper, used to save the settings for the selected_if + */ +gboolean +airpcap_if_get_driver_keys(PAirpcapHandle AdapterHandle, PAirpcapKeysCollection KeysCollection, guint * PKeysCollectionSize); + +/* + * Airpcap wrapper, used to get the decryption enabling of an airpcap driver + */ +gboolean +airpcap_if_get_driver_decryption_state(PAirpcapHandle ah, PAirpcapDecryptionState PEnable); +/* + * Airpcap wrapper, used to set the decryption enabling of an airpcap driver + */ +gboolean +airpcap_if_set_driver_decryption_state(PAirpcapHandle ah, AirpcapDecryptionState Enable); + +/* + * Save the configuration for the specified interface + */ +void +airpcap_save_driver_if_configuration(airpcap_if_info_t* fake_if_info); + +/* + * Free an instance of airpcap_if_info_t + */ +void +airpcap_if_info_free(airpcap_if_info_t *if_info); + +/* + * This function will tell the airpcap driver the key list to use + * This will be stored into the registry... + */ +gboolean +write_wlan_driver_wep_keys_to_registry(GList* key_list); + +/* + * Clear keys and decryption status for the specified interface + */ +void +airpcap_if_clear_decryption_settings(airpcap_if_info_t* info_if); + +/* + * Function used to save to the preference file the Decryption Keys. + */ +int +save_wlan_driver_wep_keys(void); + +/* + * Function used to save to the preference file the Decryption Keys. + */ +int +save_wlan_wireshark_wep_keys(GList* key_ls); + +/* + * DECRYPTION KEYS FUNCTIONS + */ +/* + * This function is used for DEBUG PURPOSES ONLY!!! + */ +void +print_key_list(GList* key_list); + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the given adapter... returns NULL if no keys are found. + */ +GList* +get_airpcap_device_keys(airpcap_if_info_t* if_info); + +/* + * Retrieves a GList of decryption_key_t structures containing infos about the + * keys for the global AirPcap driver... returns NULL if no keys are found. + */ +GList* +get_airpcap_driver_keys(void); + +/* + * Returns the list of the decryption keys specified for wireshark, NULL if + * no key is found + */ +GList* +get_wireshark_keys(void); + +/* + * Tests if two collection of keys are equal or not, to be considered equals, they have to + * contain the same keys in the SAME ORDER! (If both lists are NULL, which means empty will + * return TRUE) + */ +gboolean +key_lists_are_equal(GList* list1, GList* list2); + +/* + * Merges two lists of keys. If a key is found multiple times, it will just appear once! + */ +GList* +merge_key_list(GList* list1, GList* list2); + +/* + * If the given key is contained in the list, returns TRUE. + * Returns FALSE otherwise. + */ +gboolean +key_is_in_list(decryption_key_t *dk,GList *list); + +/* + * Returns TRUE if keys are equals, FALSE otherwise + */ +gboolean +keys_are_equals(decryption_key_t *k1,decryption_key_t *k2); + +/* + * Use this function to free a key list. + */ +void +free_key_list(GList *list); + +/* + * Returns TRUE if the Wireshark decryption is active, FALSE otherwise + */ +gboolean +wireshark_decryption_on(void); + +/* + * Returns TRUE if the AirPcap decryption for the current adapter is active, FALSE otherwise + */ +gboolean +airpcap_decryption_on(void); + +/* + * Enables decryption for Wireshark if on_off is TRUE, disables it otherwise. + */ +void +set_wireshark_decryption(gboolean on_off); + +/* + * Enables decryption for all the adapters if on_off is TRUE, disables it otherwise. + */ +gboolean +set_airpcap_decryption(gboolean on_off); + +/* + * Adds compiled version string to str + */ +void +get_compiled_airpcap_version(GString *str); + +void +get_runtime_airpcap_version(GString *str); + +#ifdef __cplusplus +} +#endif + +#endif /* __AIRPCAP_LOADER_H__ */ -- cgit v1.2.1