Написание внешней программы для взаимодействия с wpa_supplicant - PullRequest
0 голосов
/ 27 февраля 2020

Мне нужно напрямую взаимодействовать с wpa_supplicant из Python. Насколько я понимаю, к wpa_supplicant можно подключиться, используя Unix сокеты и интерфейс управления wpa_supplicant (https://w1.fi/wpa_supplicant/devel/ctrl_iface_page.html). Я написал простую программу, которая отправляет команду 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: 107 - Конечная точка транспорта не подключен

Может кто-нибудь привести пример, как вы должны выполнить «сканирование», а затем напечатать «scan_results».

1 Ответ

0 голосов
/ 27 февраля 2020

Очевидно, тип сокета, который использует wpa_supplicant (UNIX дейтаграмма), не предоставляет серверу никакого ответа. Есть несколько способов обойти это . В частности, wpa_supplicant поддерживает ответы через отдельный сокет (который находится по пути, добавленному в конце каждого сообщения).

Как ни странно, это довольно распространенная практика в Linux: / dev / log работает аналогично .

Вот программа, которая делает то, что вы просили:

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)
...