编写外部程序以与 wpa_supplicant 交互
Writing an external program to interface with wpa_supplicant
我需要直接与来自 Python 的 wpa_supplicant 互动。据我了解,可以使用 Unix 套接字和 wpa_supplicant 控制接口 (https://w1.fi/wpa_supplicant/devel/ctrl_iface_page.html) 连接到 wpa_supplicant。
我写了一个发送 PING 命令的简单程序:
import socket
CTRL_SOCKETS = "/home/victor/Research/wpa_supplicant_python/supplicant_conf"
INTERFACE = "wlx84c9b281aa80"
SOCKETFILE = "{}/{}".format(CTRL_SOCKETS, INTERFACE)
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.connect(SOCKETFILE)
s.send(b'PING')
while 1:
data = s.recv(1024)
if data:
print(repr(data))
但是我运行的时候,wpa_supplicant报错:
wlx84c9b281aa80: ctrl_iface sendto failed: 107 - Transport endpoint is not connected
有人可以提供一个例子,你会如何做一个 'scan' 然后打印 'scan_results'.
显然,wpa_supplicant 使用的套接字类型(UNIX 数据报)没有为服务器提供任何回复方式。有。 wpa_supplicant 似乎特别支持通过单独的套接字进行回复(在每条消息末尾附加的路径中找到)。
奇怪的是,这似乎是 Linux 中比较普遍的做法:/dev/log seems to work in the same way。
这是一个可以执行您要求的程序:
import socket, os
from time import sleep
def sendAndReceive(outmsg, csock, ssock_filename):
'''Sends outmsg to wpa_supplicant and returns the reply'''
# the return socket object can be used to send the data
# as long as the address is provided
csock.sendto(str.encode(outmsg), ssock_filename)
(bytes, address) = csock.recvfrom(4096)
inmsg = bytes.decode('utf-8')
return inmsg
wpasock_file = '/var/run/wpa_supplicant/wlp3s0'
retsock_file = '/tmp/return_socket'
if os.path.exists(retsock_file):
os.remove(retsock_file)
retsock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
retsock.bind(retsock_file)
replyToScan = sendAndReceive('SCAN', retsock, wpasock_file)
print(f'SCAN: {replyToScan}')
sleep(5)
replyToScanResults = sendAndReceive('SCAN_RESULTS', retsock, wpasock_file)
print(f'SCAN_RESULTS: {replyToScanResults}')
retsock.close()
os.remove(retsock_file)
我需要直接与来自 Python 的 wpa_supplicant 互动。据我了解,可以使用 Unix 套接字和 wpa_supplicant 控制接口 (https://w1.fi/wpa_supplicant/devel/ctrl_iface_page.html) 连接到 wpa_supplicant。 我写了一个发送 PING 命令的简单程序:
import socket
CTRL_SOCKETS = "/home/victor/Research/wpa_supplicant_python/supplicant_conf"
INTERFACE = "wlx84c9b281aa80"
SOCKETFILE = "{}/{}".format(CTRL_SOCKETS, INTERFACE)
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.connect(SOCKETFILE)
s.send(b'PING')
while 1:
data = s.recv(1024)
if data:
print(repr(data))
但是我运行的时候,wpa_supplicant报错:
wlx84c9b281aa80: ctrl_iface sendto failed: 107 - Transport endpoint is not connected
有人可以提供一个例子,你会如何做一个 'scan' 然后打印 'scan_results'.
显然,wpa_supplicant 使用的套接字类型(UNIX 数据报)没有为服务器提供任何回复方式。有
奇怪的是,这似乎是 Linux 中比较普遍的做法:/dev/log seems to work in the same way。
这是一个可以执行您要求的程序:
import socket, os
from time import sleep
def sendAndReceive(outmsg, csock, ssock_filename):
'''Sends outmsg to wpa_supplicant and returns the reply'''
# the return socket object can be used to send the data
# as long as the address is provided
csock.sendto(str.encode(outmsg), ssock_filename)
(bytes, address) = csock.recvfrom(4096)
inmsg = bytes.decode('utf-8')
return inmsg
wpasock_file = '/var/run/wpa_supplicant/wlp3s0'
retsock_file = '/tmp/return_socket'
if os.path.exists(retsock_file):
os.remove(retsock_file)
retsock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
retsock.bind(retsock_file)
replyToScan = sendAndReceive('SCAN', retsock, wpasock_file)
print(f'SCAN: {replyToScan}')
sleep(5)
replyToScanResults = sendAndReceive('SCAN_RESULTS', retsock, wpasock_file)
print(f'SCAN_RESULTS: {replyToScanResults}')
retsock.close()
os.remove(retsock_file)