Actually, the application which determines this information is airodump-ng
, not aircrack-ng
. From the airodump-ng
documentation, power levels are determined as:
PWR - Signal level reported by the card. Its signification depends on the driver [...]
Well, let's see if we can do better. Looking through the latest source code of the airodump-ng.c
file, we see the power gets set in the dump_add_packet(...)
function:
/* only update power if packets comes from * the AP: either type == mgmt and SA != BSSID, * or FromDS == 1 and ToDS == 0 */ if (...) ap_cur->power_lvl[ap_cur->power_index] = ri->ri_power;
After digging through several layers of abstraction, structs, and function pointers, I found that this data is filled from the function linux_read(...)
defined in the osdep/linux.c
file. This is where the ri_power
variable in the ri
struct is filled with data, and indeed it does appear to be driver specific.
Most drivers follow the Radiotap standard (as opposed to the older prism54 standard detailed below), which have several predefined fields for determining antenna power, noise, and attenuation. These fields are used directly by airodump-ng
to fill in the ri_power
variable. Some of these are already available in decibel or power values.
airodump-ng
will use either the antenna signal field (in dBm) or the dB antenna signal field (in dB) to compute the displayed signal power. Similar steps are used for the other fields, as they are all predetermined in the Radiotap specification linked to above. For example, the ri_power
using the dB Antenna Signal field can be computed as:
case IEEE80211_RADIOTAP_DB_ANTSIGNAL: if(!got_signal) { if( *iterator.this_arg < 127 ) ri->ri_power = *iterator.this_arg; else ri->ri_power = *iterator.this_arg - 255; got_signal = 1; } break;
As mentioned earlier, some devices follow the (older) prism54 specification (instead of Radiotap), which uses a fixed-length header. In this case, the RX power directly from the buffer (note this is not complete source code, just shows the paths taken to fill ri_power
):
if (tmpbuf[7] == 0x40) ri->ri_power = tmpbuf[0x33]; else ri->ri_power = *(unsigned int *)( tmpbuf + 0x5C );