Closed jantman closed 2 years ago
I'm still not entirely sure what's going on here, but it looks like the code is also running a scan, and the BSSID detection might occasionally be reporting the BSSID of a completely unrelated AP?
Ok... so, tl;dr: the current code appears to be for scanning only, not finding the currently-associated BSSID. I'm not sure why that's the case, I guess an issue in #4. Looking at e.g. the source code for iw
we can see that the nl80211 code in this project is all using phy
-based functions, but to find the currently associated BSSID, we need to look at the dev
.
My C is really rusty (it was never good to begin with), but I'll see if I can get this figured out.
Ok, I've made a lot of progress on this. After a whole lot of research, I found that pyroute2 makes use of nl80211 and includes some instructions and a decoder script for using strace
to capture Netlink socket calls. I had to recompile a very old version of strace for my system (which needed a bunch of hacks to get it to build), but I've captured and decoded the actual send/receive data generated by iw dev <wireless device> link
which gives the actual, correct information on whether the device is currently associated to an AP, and if so, the SSID and BSSID.
I'm now starting work on writing Python code using nl80211 to make those same calls.
Note to myself about strace...
I really need to also strace the python process, to compare its communication with iw
.
To compile strace 4.12 on modern Arch Linux:
wget https://strace.io/files/4.12/strace-4.12.tar.xz && tar -xvf strace-4.12.tar.xz && cd strace-4.12
cd /usr/include/linux/ && cp btrfs.h btrfs.h.orig && vim btrfs.h
and then delete all of struct btrfs_ioctl_defrag_range_args
linux/x86_64/arch_sigreturn.c
change struct ucontext
to ucontext_t
)../configure && make
./strace
to somewhere you can find/use it as strace-4.12
mv /usr/include/linux/btrfs.h.orig /usr/include/linux/btrfs.h
You can then wherever/strace-4.12 -e trace=network -x -s 16384 COMMAND
where COMMAND is something like iw dev wlp59s0 link
or python some-test-script.py
To decode the above output, we can redirect the stdout and stderr of the strace command to a file and then run the following script (which relies on pyroute2) passing the path to the output file as an argument:
#!/usr/bin/python
'''
Decoder for netlink data.
Capture the data using strace <= 4.12 like:
strace-4.12 -e trace=network -x -s 16384 python main.py 2>&1 | tee strace.out
Then decode the data like:
python decoder.py strace.out > strace.decoded
'''
import sys
from pprint import pformat
from pyroute2.common import hexdump, load_dump
from pyroute2.netlink.nl80211 import nl80211cmd
import re
from io import StringIO
SEND_RE = re.compile(r'^sendto\(\d+, "([^"]+)".*')
SEND_IOV_RE = re.compile(r'^sendmsg\(.+msg_iov\(\d\)=\[\{"([^"]+)".*')
RCV_RE = re.compile(r'^recvmsg\(.+msg_iov\(\d\)=\[\{"([^"]+)".*')
def decoded(s):
s += '\n'
i = StringIO(s)
msg = nl80211cmd(load_dump(i))
msg.decode()
return msg
def main():
with open(sys.argv[1], 'r') as fh:
for line in fh.readlines():
line = line.strip()
for rex in [SEND_RE, RCV_RE, SEND_IOV_RE]:
m = rex.match(line)
if not m:
continue
print(line)
dec = decoded(m.group(1))
for x in pformat(dec).split('\n'):
print(f'# {x}')
print('######################')
break
else:
print(f'# {str(line)}')
if __name__ == "__main__":
main()
The
--bssid
option seems to be broken. When connected to a single specific BSSID, sometimes it will throw a warning about being associated to a completely unrelated BSSID, and sometimes it will not. This appears to be intermittent, almost like a race condition, and I haven't yet been able to figure out the issue... beyond the fact that if you specify--bssid
with the BSSID that you're currently (and should) be connected to, it will intermittently show a warning about being connected to a different BSSID even though you're not...This appears to be a regression introduced by @DL6ER 's #4 migration from iwscan/iwlist to libnl.