I cannot figure out how access points determine the signal power of nearby clients.
I haven't found this information in any of the WiFi packet tutorials, so I can only assume that the power information isn't coming from the client, but is determined by the access point.
I know an application called aircrack that can determine this information, but before I jump into that and dig around, I'd like an overview of how the power is calculated. My Google skills aren't that bad, so I am surprised that so far I've been unable to dig up any information about it. Surely if aircrack can do it, this information is out there!
I was hoping that the users here can point me in the right direction?
Regarding the bounty
I guess it's time to attempt to use a bounty. In your answers, please post all links you can find that would assist anyone in understanding how this power detection works. Specific information on how it is implemented in aircrack would be perfect!
UPDATE:
As of now, using the aircrack-ng suite as an example, it looks like the power value is pulled from buf[2] in net_read(). I believe this value ultimately comes from net_cmd, which results in paired calls to net_send and net_get(). I think net_get() reads in whatever header information is sent due to the call to net_send(), and this header indicates how much data should be copied into the buffer buf[].
But now what I don't get is this — it sure looks like buf[] gets filled by the call to net_read_exact(), which is just reading data from the socket. If this is the case, and if power is a driver detail, why is the power value in the buffer? If that buffer is indeed filled by the socket data, doesn't that imply that the power is sent by the client / station? I believe that the AP / driver is in charge of supplying the power info, just like everyone has said, but just don't get this part.
Best Answer
Actually, the application which determines this information is
airodump-ng
, notaircrack-ng
. From theairodump-ng
documentation, power levels are determined as: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 thedump_add_packet(...)
function: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 theosdep/linux.c
file. This is where theri_power
variable in theri
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 theri_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, theri_power
using the dB Antenna Signal field can be computed as: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
):