IWTAN user reference
What is IWTAN
IWTAN stands for IWTAN: Wireless Topology ANalyzer. It is a Free Software, GPLv3'd library written in C with the main purpose of analyzing IEEE 802.11 wireless traffic and creating a easily-browsable data structure representing an infrastructure wireless network topology.
Wireless networks basically consists of a number of stations (clients of the net) and a number of access points. Each station is associated to an access point and uses the net sending data from and receiving by that access point.
Wireless stations and Access points can be identified by their MAC address, that should be worldwide unique. Wireless stations usually also have an IPv4 and/or IPv6 address, while access points don't (they work in layer 2).
A single AP and the stations associated to it form a BSS (Basic Service Set), identified by a single MAC address (the BSS Id). One or several wireless-interconnected BSSs form a DS (Distribution system). A DS connected to a wider net, such as the internet, forms an ESS (Extended Service Set), identified by the ESS Id, a string usually broadcasted by the access points. IWTAN is thought to analyze the traffic of one or more BSSs.
How does IWTAN work
IWTAN processes packets obtained by a pcap capture, extracting useful data about the network topology. A typical usage of IWTAN may be a program capturing data using libpcap and passing them to IWTAN in order to update the topology.
An IWTAN topology is a set of associations between stations and their AP. IWTAN also stores data about both the stations (such as the MAC address, the IP address, the time it was last seen) and the APs (such as the MAC address, the BSS id, the ESS id, the data rate, the signal strength). These data can be retrieved by the user using simple functions.
From different kind of packets, IWTAN can extract different kind of information. The type of analyzed data does not depend on IWTAN. The library just process any (significant) kind of packets and searches for interesting information. It is a task of the user to pass IWTAN interesting packets, making the wireless adapter capture frames as low-level as possible, as we'll see.
Stations and access points send to each other IEEE 802.11 Radiotap Header frames. This frames contain 802.11 WLAN frames, that may contain Wireless Management frames or Wireless Data frame. Wireless data frame contain regular traffic, such as IP packets. Most of the wireless adapter drivers, even in monitor mode, don't capture the Radiotap headers but just the WLAN frame, witch discards much interesting data. In the scheme you can see what kind of data can be extracted by different kinds of packets.
What data from what frames/packages type
Let's have some examples.
- IWTAN is given a Radiotap header frame. This frame is received by the access point (let's call it AP) and contains an IP packet from a host (H) in the internet to a station (STA) in the BSS. From such a kind of packet IWTAN can extract much useful information.
- From the radiotap header we know some physical data like the signal strength, the data rate, the channel frequency.
- The WLAN frame tells us some layer-2 data like the source (AP) and destination (STA) MAC address. This frame also tells us if the packet is sent from an access point to a station or vice-versa. In this way we can add a station and an access point to out topology.
- The layer 3 (IP) packets tells us another information: the STA IP address. We can also obtain the H IP address, but we just don't care because it is outside the BSS and not part of the topology.
- Now let's assume the packet given to IWTAN is still radiotap-level but is now a beacon frame by the AP to broadcast its ESS id. We are now talking about a WLAN management frame instead of a data frame (so it does not contain an IP packet). From this kinds of packet we can obtain:
- The same physical data from the radiotap header;
- The ESS id from the management frame.
- Anyway, as said before, some wireless adapter drivers discard by default the radiotap header and gives to IWTAN just the WLAN frame. IWTAN can process this kinds of frames, but obviously cannot obtain physical data from them. So let's assume that IWTAN is given the same WLAN frame of the example above (an IP packet from a Host H to a station STA through an access point AP), without the Radiotap header. Analyzing this package, IWTAN can tell that there is an access point and a station, but don't know the signal strength.
How to use IWTAN
IWTAN provides some structures, one function to update the context, several data browsing functions, and some utility function.
Both the updating and browsing function use a context, witch is a data structure that contains all data obtained while processing packets. The number of different contexts created by an application is mostly like to be one, but several may exist. Several context may be useful, for example, if the program is centralized but obtain packets from geographically distant capture devices that the user want to keep separated.
Note that, when compiling a program using this library, you have to include both iwtan_data.h and iwtan_analyze.h, and, when compiling, link them against other libraries like (at least) libiw and libpthread with a gcc command like:
gcc iwtan_data.c iwtan_analyze.c PROGRAM.c -liw -lpthread -o OUTPUT
where PROGRAM.c is the file(s) containing the program code, and the other options link the libiw, and libpthread libraries.
An example program
An example program is provided in iwtan_example.c. What it does is simply capturing any kind of packet with libpcap from a capture file or a device and process them with IWTAN. The program terminates when a SIGINT (CTRL-X) signal is received and prints some data by the context, before freeing it.
To invoke it for reading by a capture device, type:
./iwtan_example -d ETHN where ETHN is the capture device.
To invoke it for reading by a packet capture file, type:
./iwtan_example -f FILENAME.pcap
Data structures
The data structures needed by the user, defined in
iwtan_data.h are:
- iwtan_context, witch defines an IWTAN operating context.
- ip4_address, ip6_address, mac_address, witch defines some address types.
- iwtan_ap witch represents a WLAN access point. It is defined as follow:
typedef struct {
short WEPped;
unsigned int dataRate;
unsigned short antenna;
unsigned int frequency;
short type;
short signal;
mac_address* bssId;
char* essid;
char* description;
unsigned int associations;
time_t lastSeen;
} iwtan_ap;
- iwtan_station, witch defines a WLAN station as follows:
typedef struct {
ip4_address ip4;
mac_address* mac;
ip6_address ip6;
time_t lastSeen;
} iwtan_station;
- Some other structure are needed for functions returning a linked list of stations or access points.
iwtan_ap_el is an element of a linked list of access points. It is defined as follows:
typedef struct _wi_ll_ap_el{
iwtan_ap* ap;
struct _wi_ll_ap_el* next;
} iwtan_ap_el;
- iwtan_station_el is an element of a linked list of stations. It is defined as follows:
typedef struct _wi_ll_station_el{
iwtan_station* station;
struct _wi_ll_station_el* next;
} iwtan_station_el;
- iwtan_association represents an association between an AP and a station. It is defined as follows:
typedef struct {
iwtan_station* station;
iwtan_ap* ap;
} iwtan_association;
Context and refreshing functions
- int iwtan_context_initialize(iwtan_context* context);
Initializes an empty context. This function must be called once, after the context is created and before is is used.
- int iwtan_refresh_data(unsigned int length, const u_char* pktBody, int packetType, iwtan_context* context);
Refresh the context data structure extracting the information by a packet passed by argument.
length is the length of the packet in bytes.
pktBody is a pointer to the packet body.
packetType is the packet type as defined by pcap.h (DLT_*)
Returns 0 in case of no errors. Returns 1 if the packet type could not be processed.
- int iwtan_context_destroy(iwtan_context* context);
Destroy a context, when no longer needed, freeing all its data.
Browsing functions
- iwtan_station_el* iwtan_get_by_AP(mac_address* bssId, iwtan_context* context);
Get a linked list of wi_stations_el containing a copy of the stations currently associated to the AP with the given MAC address.
All the stations properties are copied so that they may be used thread-safely.
The function iwtan_free_stations_ll() should be called when the list and the stations are no longer needed.
Returns NULL if no associations were found, otherwise a reference to the first element of the list.
Function is thread-safe.
- iwtan_ap* iwtan_get_by_station(mac_address* stMac, iwtan_context* context);
Get a copy of the access point currently associated to the station with given MAC address.
All the AP properties are copied so that they may be used thread-safely.
The function iwtan_free_AP() should be called when the AP is no longer needed.
Returns NULL if no associations were found, otherwise a reference to the Access Point.
- iwtan_station_el* iwtan_get_all_stations(iwtan_context* context);
Get a list of (elements referring copies of) all the stations currently present in the database ordered by their MAC address.
All the stations properties are copied so that they may be used thread-safely.
The function iwtan_free_stations_ll() should be called when the list and the stations are no longer needed.
Returns the first element of the list.
- iwtan_ap_el* iwtan_get_all_APs(iwtan_context* context);
Get a list of (elements referring copies of) all the Access points currently present in the database ordered by their MAC address.
All the APs properties are copied so that they may be used thread-safely.
The function iwtan_free_ap_ll() should be called when the list and the stations are no longer needed.
Returns the first element of the list.
- iwtan_association* iwtan_get_all_associations(iwtan_context* context, unsigned int* elementsN);
Get an array of (copies of) all the associations between APs and Stations currently present in the database, ordered by the stations MAC address.
All the elements properties are copied so that they may be used thread-safely.
The function iwtan_free_ass_array() should be called when the array of associations are no longer needed.
Returns a pointer to the first element of the array and writes in elementsN the number of element (array size).
- iwtan_ap* iwtan_get_by_essid(char* essid, iwtan_context* context);
Get an AP with the given essid.
All the AP properties are copied so that they may be used thread-safely.
The function iwtan_free_AP() should be called when the AP is no longer needed.
Returns a pointer to the copied AP or NULL if an AP with the given MAC address was not found.
Function is thread-safe.
Data utility functions
- int iwtan_free_stations_ll(iwtan_station_el* freeEl);
Free a linked list of iwtan_station_el elements (such as the one created by iwtan_get_by_AP). Free both the elements and the list.
- int iwtan_free_AP_ll(iwtan_ap_el* freeEl);
Free a linked list of iwtan_ap_el elements (such as the one created by iwtan_get_all_aps). Free the elements and the list.
- int iwtan_free_ass_array(iwtan_association* ass, int size);
Free all the elements of an array containing associations with the number of elements given by argument. Also frees the array.
- int iwtan_free_AP(iwtan_ap* ap);
Free an access point and all its elements. Returns 0 only on success.
- int iwtan_free_station(iwtan_station* station);
Free a station and all its elements. Returns 0 only on success.
- int iwtan_cmp_mac(mac_address* mac1, mac_address* mac2);
Compare two mac addresses. Returns 0 if the two given addresses are the same, >0 if mac1>mac2, <0 otherwise.
- char* iwtan_ip4toa(ip4_address ip4, char* result);
Convert an IPv4 address to a string in the standard notation.
The string will be stored in the address pointed by result, that must be of size 16 at least.
Returns a pointer to the string or NULL on errors.
- char* iwtan_ip6toa(ip6_address ip6, char* result);
Convert an IPv6 address to a string in the standard notation.
The string will be stored in the address pointed by result, that must be of size 40 at least.
Returns a pointer to the string or NULL on errors.
Notes about performance and portability
IWTAN applications are thought to be silent, witch means that its analyze over a network may not be seen, at network level, by anyone. What a regular PCAP application does is just capture flying packets, without interfering with the network transmissions. In this way, for example, the network performance is not affected.
IWTAN is thread-safe: access to write and read from a context are mutual excluded using a pthread lock. So there may be two concurrent threads, one calling the iwtan_refreshData() function, and the other calling any data-reading function, such as iwtan_get_all_APs(), keeping the data structure integrity.
IWTAN is portable and should run on any POSIX-compatible platform.
The memory used by this library is very small and there should not be memory leakage. Running a benchmark on a normal computer (1.66MHz Intel Centrino with a DDR RAM) resulted that IWTAN can process up to 120 packets per millisecond. Monitoring any packet flying over a regular wireless network, the CPU usage will be about 0.1% and the allocated context data structures will never be greater then some Kb.
Bug submission
Any problem can be submitted to my e-mail address: cornolti-at-cli-dot-unipi-dot-it.
For any bug about wrong extracted data, memory leakage, bad package data interpretation, and everything regarding packets processing, please attach a pcap capture of the packet(s) causing the bug.
Copyright
Copyright (C) 2008 Marco Cornolti
IWTAN (IWTAN: Wireless Topology ANalyzer) 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 3, or (at your option) any later version.
IWTAN 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 IWTAN; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.